自从著名设计师 Ethan Marcotte(@beep)在 A List Apart上发表了一篇名为《 Responsive Web Design》的文章之后,响应式网页设计(RWD,即 Responsive Web Design)的身影就出现在了公众面前。自此就有了响应式 Web 设计这个概念。从提出这个概念到今天已经有十多年的时间了。在这十多年来,CSS 也发生了巨大的变化,新增了很多新的特性,近两年尤其如此,近两年尤其如此(详细请参阅《2022 年的 CSS》一文)。这些变化,对于响应式Web设计的开发也有较大的改变。Una Kravets(@Una)大神,在2021的Google I/O 大会上的分享,提出 新的响应式:组件驱动式 Web 设计。Web 生态即将进入响应式 Web 设计的新时代,并转变我们对其含义的看法,也为会Web设计带来新的变化。组件式驱动 Web 设计(或开发)也被称为是下一代响应式 Web 设计(或开发)。如果你对这方面话题感兴趣的话,请继续往下阅读。
文章链接:
- 《 Responsive Web Design》(地址:https://alistapart.com/article/responsive-web-design/)
- 《2022 年的 CSS》(地址:https://www.w3cplus.com/css/what-is-new-css-in-2022.html)
- 《新的响应式:组件驱动式 Web 设计》(地址:https://io.google/2021/session/a1760fa3-879a-4e98-a616-994ca8d3aab5/?lng=zh-CN)
响应式Web设计的发展历程
既然要聊响应式Web设计,那么我们就花一点篇幅和时间简单地了解一下其发展历程。
众所周知,自从 Tim Berners-Lee 创建第一个 Web页面(大约在1991年8月份左右)到90年代末,Web页面都是非常简陋的:
直到90年代末20年代初,Web设计和用户体验随着 CSS 的到来才慢慢地有了美感,Web页面看起来开始像我们今天使用的网站:
正如上图所示,越往后,Web 的 UI 越来越丰富,越来越漂亮。这也让 Web 开发人员不得不在布局、设计和排版等方面花费更多的时间。虽然 Web 开发人员为 Web 布局花费不少时间,但在这个过程中,也积累了很多不同的布局方法。在早期,Web 开发人员主要采用 固定宽度 和 流式布局 两种布局方案来实现 Web 页面的布局。特别是流式布局,自 Glenn Davis提出和推广之后,可谓是轰动一时,并且长期以来,都认为流式布局就是响应式Web布局。
流式布局(Liquid Layout)可以调整Web页面尺寸以适应不同的显示器分辨率或浏览器窗口的大小。
来看一个流式布局的简单示例:
Liquid Page Layout Example@nickpettitCodePen
(地址:https://codepen.io/nickpettit/pen/dyZwVg)
(地址:https://codepen.io/nickpettit)
(地址:https://codepen.io/)
但流式布局并不是完美的。使用流式布局的Web页面上,内容可能会溢出,在较小的屏幕上文字可能会换行,在较大的屏幕上可能会有很多不必的空白。
大多数流体布局在 800px x 600px
到 1280px
宽或更大的屏幕分辨率下看起来还不错。然而,如果我们能把它分割得更细一些,比如为 800px ~ 1024px
、1024px ~ 1280px
以及1280px
以上的分辨率提供不同的定制布局,那效果会更佳。同样,对于 640px ~ 800px
、320px ~ 640px
、240px ~ 320px
以及 240px
以下的分辨率也可以定制不同的布局。
大约在 2004 年的时候,Cameron Adams(@themaninblue)(地址:https://codepen.io/)在他的博文《Resolution dependent layout》(地址:https://www.themaninblue.com/writing/perspective/2004/09/21/)提出了基于屏幕分辨率来动态构建Web布局,即 使用JavaScript根据浏览器窗口大小加载不同CSS文件。
<!-- Narrow style sheet --> <link rel="alternate stylesheet" type="text/css" href="css/narrow.css" title="narrow"/> <!-- Default style sheet --> <link rel="stylesheet" type="text/css" href="css/normal.css" title="default"/> <!-- Wide style sheet --> <link rel="alternate stylesheet" type="text/css" href="css/wide.css" title="wide"/> <!-- Included JavaScript to switch style sheets --> <script src="scripts/dynamiclayout.js" type="text/javascript"></script>
注意,在所有 标签上title
属性的值分别为 narrow
、default
和 wide
,并且在 dynamiclayout.js
中有一个 DynamicLayout()
函数,将会根据 标签的title
属性的值来调用不同的样式表:
function dynamicLayout(){ var browserWidth = getBrowserWidth(); // Narrow CSS rules if (browserWidth < 640){ changeLayout("narrow"); } // Normal (default) CSS rules if ((browserWidth >= 640) && (browserWidth <= 960)){ changeLayout("default"); } // Wide CSS rules if (browserWidth > 960){ changeLayout("wide"); } }
@Kevin Hale 的博文《 Dynamic Resolution Dependent Layouts》详细介绍该技术。
这种布局技术后来就以 Cameron Adams 博客文章标题命名,被称为 分辨率相关的布局。这种布局技术虽然会额外增加开发者(开发者需要为不同定制的布局提供不同样式表)工作量,但在CSS媒体查询流行之前还是很受欢迎的。它也被称为是早期的 CSS 媒体查询(通过JavaScript查询断点)。
虽然这种依赖动态分辩率布局的方案可以在不同的分辨率下提供更佳的体验,但随着 2005年08月10日 Opera 软件公司推出Opera Mini(地址:https://www.webdesignmuseum.org/web-design-history/opera-mini-2005)和 2007年01月09是第一台 iPhone(地址:https://www.webdesignmuseum.org/web-design-history/steve-jobs-introduced-the-first-iphone-2007)手机的出现,市场上不同品牌,不同分辨率的移动端以及品牌商自己的Web浏览器就越来越多。
在这种环境之下,基于动态分辨率加载不同的样式表已不太现实,Web开发者不得不想出其他的方案来适应不同的屏幕尺寸。在很长一段时间,甚至到今日,为了适应不同屏幕的尺寸适配,为移动端单独创建一个网站,即 移动子域名网站。比如 Facebook的桌面版本和移动端版本,采用两个不同的域名来访问:
如此一来,开发人员要开发两个版本,相应的工作量就更大了,特别对于要快速响应和试错的Web应用来说,难度变得更大。
Web开发人员为了能改善这种现象,在 2010 年的时候,Ethan Marcotte(@beep)基于 John Allsopp(@johnallsopp)的 《网页设计的道(A Dao of Web Design)》(地址:https://alistapart.com/article/dao/),提出响应式Web设计思路(《Responsive Web Design》)(地址:https://alistapart.com/article/responsive-web-design/)。从此响应式Web设计(Responsive Web Design,简称 RWD)的身影就出现在了公众面前。
Ethan Marcotte(@beep)在《Responsive Web Design》(地址:https://alistapart.com/article/responsive-web-design/)中提到,响应式这个词源自于建筑学领域,原本指的是建筑物本身会“响应”实际的使用情况,来自我调整。在Web开发领域,“响应式”的意思就变成了,我们开发的Web页面会“响应”用户的设备尺寸而自动调整布局。在这篇文章中提到过,我们可以基于 流体网格(Fluid Grids)、灵活的图片(Flexible Images)和媒体查询(Media Queries) 三种技术来构建一个响应式Web网站或Web应用。
另外,Ethan Marcotte(@beep)构建了第一个具有响应式的Web网页,可以说是响应式Web设计经典案例之一(只可惜现在打不开了):
那通过这个示例,大家对响应式Web设计是什么样的有了一个初步的了解了。其实,Ethan Marcotte 在他的文章中就提到:
未来我们应该这样,随着访问网页的设备增加我们不会为每个设备单独设计,而只会做一份设计,把每个设备作为这份设计要照顾的一个方面。
也就是说,每个设备上都会去追求最佳的用户体验,设计会自动适应各个设备。在过去的时代,设计师精确的知道自己的媒介材质,比如一张 A4 纸张,一个名片,或者一张海报。但是在我们这个多屏时代,Web 设计必须有这样的思维,我们要为“任意尺寸”而去设计。
自 Ethan Marcotte 提出响应式Web设计思路以及基于不同断点(CSS 媒体查询替代JavaScript查询设备屏幕分辨)实现不同终端设备屏幕分辨率布局已有十多年了。大家都说,每十年就会看到一个生态系统迅速的发展,其中 CSS 也不另外。尤其是这两年,CSS 新增了很多新的特性,比如大家最为期待的容器查询特性@container
、级联分层@layer
以及 CSS作用域 @scope
等。
正如 Una Kravets (@Una) 在2021的Google I/O 大会上的分享(地址:https://io.google/2021/session/a1760fa3-879a-4e98-a616-994ca8d3aab5/?lng=zh-CN)所说:
随着用户偏好查询、容器查询以及其他设备类型查询的出现(CSS新特性),Web社区即将进入响应式 Web 设计的新时代,并改变我们对其含义的看法。
换句话说,下一代响应式Web设计即将到来,或者说已经来到了我们身边。
响应式Web设计的现状
在聊一下代响应式Web设计之前,我们就要对响应式Web设计的现状有所了解。我们分别从两种不同角色(Web设计师和Web开发者)的角度来看响应式 Web 设计的现状。
先从 Web 设计师的角色来聊。
时至今日,虽然已是移动终端的天下,但如果要给不同终端提供设计稿的话,Web 设计师还是会依旧为不同的设备终端提供不同的设计稿。比如,为不同的设备视窗尺寸(如手机,平板和桌面端)提供不同的设计稿:
我们来看下简化后的不同版本的设计线框图,如下所示:
在上图中,设计师为卡片(Card)提供了三种不同的 UI 效果。虽然卡片在不同设备视窗下有着不同的UI效果,但他们构成的元素是相同,都有卡片容器、卡片缩略图、卡片标题 和 卡片描述等:
作为Web设计师,你已经使用了多个版本的布局来展示同一个组件三种不同状态下的UI变化。可以说把足够多的信息传递给了Web开发者!到这一步,Web 设计师已给 Web 开发者提供了具有响应式的Web设计稿。
接下来,再从另一种角色(Web开发者)来看响应式Web设计的现状。对于 Web 开发者而言,要实现上图中三种状态下的卡片UI效果非常简单。借助 CSS 媒体查询特性,在不同断点下调整CSS样式规则即可:
/* Mobile First */ .card { display: flex; flex-wrap: wrap; gap: 10px; } /* Tablet */ @media (min-width: 700px) { .card { gap: 20px } } /* Laptop and Desktop */ @media (min-width: 1024px) { .card { position: relative } .card__thumb { position: absolute; inset: 0; } }
这种方式只能适合于同一组件独立存在于不同版本下。就示例的设计稿来看,在桌面端有两种效果的卡片,为了满足该设计效果,我们需要额外添加一些类名,在不同状态下为卡片处理不同的UI效果:
CSS样式代码可能会是像下面这样:
/* Mobile First */ .card { display: flex; flex-wrap: wrap; gap: 10px; } /* Tablet */ @media (min-width: 700px) { .card--vertical { gap: 20px } } /* Laptop and Desktop */ @media (min-width: 1024px) { .card--featured { position: relative } .card--featured .card__thumb { position: absolute; inset: 0; } }
看上去是不错,但问题是,只有当视窗宽度大于一个特定的值时(常指的分辨率断点值),相应的组件变体才会生效,比如当视窗宽度大于 700px
时,.card--vertical
卡片UI效果才生效;当视窗宽度大于1024px
时,.card--featured
卡片UI效果才生效。换句话说,如果要在平板端看到.card--featured
卡片效果就无法看到,因为它的媒体查询在 1024px
或更大的视窗宽度下才会生效。
不仅如此,Web的内容是动态的,有的时候输出的内容可能和设计预定的卡片数量不相符合,那么在这种情况之下,要么会有一个空的空间,要么卡片会扩展以填补容器的剩余(或可用)空间。比如我们这个示例中,在视窗宽度为 700px
或更大的视窗宽度中,.card--vertical
和 .card--featured
都有可能出现这样的场景。
针对这样的场景,Web设计师可能更希望有额外的UI效果给卡片。这部分我们放到下一节来聊。
简单地说,目前的响应式 Web 设计主要方案还是利用 CSS 媒体查询特性在不同的终端上提供布局的切换。虽然他能满足 Web 页面布局大部分场景,但也相对丧失了一些其他能力,比如说将响应式的样式注入到组件本身的能力。换句话说,基于视窗宽度查询构建的响应式Web页面,尤其是响应式组件,其能力是有限的。
▐ CSS 媒体查询的不足
在上一节中我们一起探讨了 Web 开发者可以借助于 CSS 媒体查询特性来查询视窗宽度(或设备其他特性)为 Web 页面在不同终端提供差异化的布局。但也暴露出很多不足之处,甚至是明显的能力不足。就拿前面示例来说,卡片组件有三种差异化的UI效果,这些差异化的UI效果是取决于浏览器视窗宽度,也就意味着卡片组件不能根据其父容器宽度去调整 UI 风格。这就限制了开发者 只能在视窗宽度大于某个特定值时(断点) 使用一个组件的特定样式。例如视窗宽度到达 700px
或大于700px
时,卡片组件从默认的.card
(水平)状态切换到垂直(.card--vertical
)状态。也就是说,如果我们想在小于700px
宽度的视窗下,使用垂直状态(.card--vertical
)卡片效果是不行的:
另外一点就是当服务端吐出的数据和设计师预设的数量不一致时,最终的Web效果有可能不是设计师期望的。比如只有一张卡片、两张、三张或更多,而设计稿中包含三张,这种情况之下,Web开发的实现的效果可能会像下图这样:
正如上图所示,如果只有一张卡片数据吐出的时候,整个卡片宽度会扩展与容器宽度相等(拉伸)。此时,卡片宽度太宽导致用于卡片上的缩略图被拉抻,有可能会使缩略图变得模糊。
事实上呢?这只是Web开发者的一厢情愿,设计师真正的意图可能是像下图这样:
在这种场景之下,使用 CSS 媒体查询特性实现起来会比较棘手,但使用 CSS 容器查询特性,就会容易地多,我们可以通过查询卡片父容器来决定如何显示卡片去解决这些问题。
如果用一然话来概述的话:
虽然 Web 开发者可以使用全局的视窗信息来设置组件的样式,但组件仍然不能拥有自已的样式,而且当我们的设计系统基于组件而不是基于页面时,那么媒体查询就无能为力!
庆幸的是,生态系统正在改变,而且这两年尤其突出。比如说,我们一直期望的容器查询特性就如约而至。如果我们将组件自身的响应式样式思路从查询视窗转换到查询其祖先容器,是不是前面的问题就可以轻易解决。除此之外,早期的CSS媒体查询只能查询视窗宽度和媒体特性,但不能查询用户对设备喜好的设置。不过,这两年CSS媒体查询特性也有巨大的变化,我们除了查询媒介(设备)特性之外,也可以查询用户偏好设置。
正如 Una Kravets 所言:
Web生态再一次让CSS腾飞,这些新的特性将会让响应式Web设计注入新的能力。我们也将进入响应式设计的新时代,并转变我们对其含义的看法。
下一代响应式Web设计
当媒体查询被运用于 CSS 中时,“响应式Web设计”(Responsive Web Design)一词就被 Ethan Marcotte 在 2010年创造出来。从那时起,Web设计师和开发人员就开始使用响应式Web设计的方法来设计和开发一个沉浸式的Web页面或Web应用,以实时适配当今看上去无底洞的终端设备。
今天,当我们提到响应式Web设计时,首先想到的是Ethan Marcotte(@beep)的 《Responsive Web Design》(地址:https://alistapart.com/article/responsive-web-design/)博文中提到过的基于 流体网格(Fluid Grids)、灵活的图片(Flexible Images)和媒体查询(Media Queries) 三种技术来构建一个适应不同屏幕尺寸或不同移动终端设备的 Web 页面。
Web 开发者使用 CSS 媒体查询来改变整个页面的布局,并从上到下调整移动手机、平板电脑和桌面端的设计尺寸。这种方法很有效,而且效果很好,但它有一个明显的缺陷,即 整个屏幕同时响应,或者说整个页面同时响应。虽然该响应方式确实对用户的体验有一些较大的影响,但不能响应个别用户的需求,也缺乏将响应式注入组件本身。
好消息是,生态系统正在改变,而且进步非常迅速。Web 设计师和Web平台的工程师正在开始用一种新的响应式技术方案来构建Web页面,这种方案被称为组件驱动式Web设计(Component-Driven Web Design)。