▐ 组件驱动式Web设计
我们今天使用的响应式 Web 设计方法很快就会被认为是过时的,就像我们从90年代最初的基于表格的HTML开发过渡到现在的感觉一样。
Web 设计师现在要克服的挑战是,目前的响应式 Web 设计方法本质上是一种一刀切的方法,把整个页面和用户体验当作一个整体,没有任何个性化。
基于视窗的媒体查询(CSS 媒体查询)给我们提供了许多媒体查询的能力,但缺少为我们的Web设计提供精细度的能力,并创造一个对用户、他们的环境和他们在页面上采取的行动来说是独特的体验。我们也缺乏将响应式样式注入组件本身的能力。
这里所说的组件是Web上的元素,可以由其他设计元素的集合或分组组成。如果我们把组件看成是由积木组成的,并把这个概念应用到像幻灯片、卡片或内容块这样的常见UI元素的构造中,就会更容易理解,在不久的某一天,我们可能会把响应式设计样式注入单个组件或积木中,以定制和调整用户的体验,而不是把一套固定的样式和规则应用于整个页面的布局。
我们可以使用全局视窗信息来控制元素的字体大小和最大宽度等样式,或者调整这些组件的背景图像和布局,但它们仍然无法控制拥有自己的样式。当我们的响应式设计系统是基于组件的,而不是基于页面的时候,这种限制就更难了。
好消息是,全世界的Web设计师和开发人员正在努力改变响应式Web设计的生态系统。尽管为了改变我们对响应式设计的思考方式以及组件如何适应其周围环境,需要进行基本的设计思维过程的改变,但响应式设计专业人员处理响应式Web设计的方式正在快速变化。
现在为创新之火推波助澜的是CSS和灵活布局的快速发展,比如添加了一些新的查询规则、Flexbox 和 Grid布局。这里所取得的进步正在迅速迎来一个新的响应式Web设计的时代,而这个时代就在地平线之外。
CSS生态快速的发展,即将彻底改变响应式 Web 设计的概念!
现在,在我们被引入响应式 Web 设计这个激进的新概念的十多年后,我们又一次见证了响应式设计生态系统的演变,即 CSS新增的特性将直接基于组件而不是基于页面注入样式响应能力。这种能力被称为 组件驱动Web设计(Component-Driven Web Design),基于组件驱动的开发将会成为一种真正流行的开发模式。
为了理解这种开发模式的转变,并为即将到来的变化浪潮做好准备,让我们看看在响应式Web设计运动中我们可以期待的变化,以及这可能会如何改变我们对待响应式设计的概念。
▐ 响应用户的需求
你可能对基于视窗可视区域大小的媒体查询(通过 min-width
、max-width
、min-height
、max-height
、orientation
和 aspect-ratio
等)比较熟悉,比如:
@media (max-width: 45rem) { /* 视窗小于 45rem */ } @media (min-width: 45rem) { /* 视窗大于 45rem */ }
这只是 CSS 的 @media
最基础的一部分规则,事实上,@media
规则大约包含了 24
个可供查询的特性,其中大约 19
个查询规则得到较好的支持,详细的可以阅读《图解CSS: CSS媒体查询》(地址:https://www.w3cplus.com/css/css-media-queries-guide.html)一文。在这些新增的查询特性中是用来改善用户体验的,比如 Media Queries Level 5(地址:https://www.w3.org/TR/mediaqueries-5/#mf-user-preferences)规范中的第十一部分,能够让你根据用户自身的特定偏好和需求来设计 Web 体验。
也意味着这些新增的媒体查询特性允许你根据用户的偏好来调整用户的体验。现在很多设备提供了一些用户偏好的设置。比如在 Mac 电脑上,用户可以根据自己喜好做一些设置:
CSS媒体查询提供了一些用户喜好的查询特性,这些特性可以识别出用户在系统上的偏好设置,帮助Web开发者构建更加健壮和个性化的 Web 体验,特别是对于那些具有可访问性需求的用户。
- prefers-reduced-motion
Web页面或应用难免少不了用一些动效来点缀,但有些用户不喜欢这些动画效果,甚至对于少数用户来说,这些动效会让他们身体不适。这就是为什么现在大多数设备都支持一种方法让用户根据自己的喜好来做设置。
使用prefers-reduced-motion
媒体查询用于检测用户的系统是否被开启了动画减弱功能。比如下面的这个示例,将会展示一组令人心烦的动画,不过当你开启了系统的“减少运动”后就能看到动画减弱的效果了。
.pulse { animation: pulse 2s infinite; } @media screen and (prefers-reduced-motion: reduce) { .pulse { animation: none; } }
示例效果演示的是prefers-reduced-motion
媒体特性如何让animation
停止,其实CSS的transition
也可以实现动画效果,加上并不是所有设备对动效都有一个很好的性能支持(毕竟动效是较耗性能的),因此,我们可以像下面这样来写CSS:
@media screen and (prefers-reduced-motion: reduce), (update: slow) { * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }
这段代码强制所有使用动画持续时间或过渡持续时间声明的动画以人眼无法察觉的速度结束。当用户要求减少动画体验,或者设备屏幕刷新率较低时,比如廉价智能手机,它就能工作。
另外,Eric Bailey 在他的文章《Revisiting prefers-reduced-motion, the reduced motion media query》(地址:https://css-tricks.com/revisiting-prefers-reduced-motion/)中提出了一个观点:
“并不是每一个可以访问网络的设备都可以呈现动画,或者流畅地呈现动画。”
对于刷新率低的设备来说,可能会导致动画出现问题,比如动画卡顿。这样的话,删除动画可能是更好的选择。我们可以将 prefers-reduced-motion
和 update
结合在一起使用:
@media screen and (prefers-reduced-motion: reduce), (update: slow) { * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } }
这段代码强制所有使用animation-duration
或transition-duration
声明的动画以人眼难以察觉的速度结束。当一个人要求减少动效体验,或者设备有一个刷新率较低的屏幕,比如电子墨水或廉价的智能手机,它就能发挥作用。
但需要注意的是,使用动态减弱并不意味着“没有动效”,因为动效在Web页面中传达信息能起到至关重要的作用。相反,你应该使用一个坚实的、去除非必须的动效基础体验去引导这些用户,同时逐步增强没有此项偏好设置的其他用户的体验。
如果你对减弱动效效果这方面技术感兴趣的话,还可以阅读:
- Revisiting
prefers-reduced-motion
, the reduced motion media query(地址:https://css-tricks.com/revisiting-prefers-reduced-motion/)(地址:https://css-tricks.com/revisiting-prefers-reduced-motion/)(地址:https://css-tricks.com/revisiting-prefers-reduced-motion/) - Meeting “2.2.2 Pause, Stop, Hide” with
prefers-reduced-motion
(地址:https://hidde.blog/meeting-2-22-pause-stop-hide-with-prefers-reduced-motion/)
(地址:https://hidde.blog/meeting-2-22-pause-stop-hide-with-prefers-reduced-motion/) - Respecting Users’ Motion Preferences(地址:https://www.smashingmagazine.com/2021/10/respecting-users-motion-preferences/)
- Designing With Reduced Motion For Motion Sensitivities(地址:https://www.smashingmagazine.com/2020/09/design-reduced-motion-sensitivities/)
- Accessible Web Animation: The WCAG on Animation Explained(地址:https://css-tricks.com/accessible-web-animation-the-wcag-on-animation-explained/)
- Accessible Animations in React(地址:https://www.joshwcomeau.com/react/prefers-reduced-motion/)
- prefers-color-scheme
你可能知道了,macOS系统和iOS13之后,苹果设备具备Dark Mode效果(地址:https://www.w3cplus.com/blog/tags/700.html),就是用户可以根据自己的喜好来选择系统提供的色系:
使用 prefers-color-scheme
查询特性可以让你对用户是否打开了设备上Dark Mode来做出响应。换句话说,给Web页面或应用添加Dark Mode只需要几行代码即可。首先我们默认加载的主题是亮色系,我们可以在 :root
中声明亮色系所需要的颜色,比如:
:root { --text-color: #444; --background-color: #f4f4f4; }
然后通过媒体查询prefers-color-scheme: dark
为暗色系重置所需要的颜色:
@media screen and (prefers-color-scheme: dark) { :root { --text-color: rgba(255,255,255,.8); --background-color: #121212; } }
使用prefers-color-scheme
来定制不同外观主题时,还可以和theme-color
以及 color-scheme
结合起来使用。这将能控制系统应用的(比如浏览器)主题颜色:
而 color-scheme
这个 CSS 属性和的name
为theme-color
是相同的。它们都是让开发者更容易根据用户的喜好设置来控制 Web应用或页面的主题,即 允许开发者根据用户喜好设置添加特定的主题样式。其实 color-scheme
属性和 相应的标签与prefers-color-scheme
相互作用,它们在一起可以发挥更好的作用。最重要的一点是, color-scheme
完全决定了默认的外观,而prefers-color-scheme
则决定了可样式化的外观 。
假设你有下面这样的一个简单页面:
<head> <meta name="color-scheme" content="dark light"> <style> fieldset { background-color: gainsboro; } @media (prefers-color-scheme: dark) { fieldset { background-color: darkslategray; } } </style> </head> <body> <p> Lorem ipsum dolor sit amet, legere ancillae ne vis. </p> <form> <fieldset> <legend>Lorem ipsum</legend> <button type="button">Lorem ipsum</button> </fieldset> </form> </body>
页面上中的CSS代码,把元素的背景颜色设置为gainsboro
,如果用户更喜欢暗色模式,则根据prefers-color-scheme
媒体查询,将的背景颜色设置为darkslategray
。
通过 元数据的设置,页面告诉浏览器,它支持深色(
dark
)和亮色(light
)主题,并且优先选择深色主题。
根据操作系统是设置为深色还是亮色模式,整个页面在深色上显示为浅色,反之亦然,基于用户代理样式表。开发者没有额外提供 CSS 来改变段落文本或页面的背景颜色。
请注意, 元素的背景颜色是如何根据是否启用了深色模式而改变的,它遵循了开发者在页面上提供的内联样式表的规则。它要么是gainsboro
,要么是darkslategray
。
上图是亮色模式(light
)下,由开发者和用户代理指定的样式。根据用户代理的样式表,文本是黑色的,背景是白色的。元素的背景颜色是gainsboro
,由开发者在内联的式表中指定的颜色。
上图是暗色模式(dark
)下,由开发者和用户代理指定的样式。根据用户代理的样式表,文本是白色的,背景是黑色的。元素的背景色是darkslategray
,由开发者在内联样式表中指定的颜色。
按钮元素的外观是由用户代理样式表控制的。它的颜色被设置为ButtonText
系统颜色,其背景颜色和边框颜色被设置为ButtonFace
系统颜色。
现在注意元素的边框颜色是如何变化的。border-top-color
和border-bottom-color
的计算值从rgba(0,0,0,.847)
(偏黑)切换到rgba(255, 255, 255, .847)
(偏白),因为用户代理根据颜色方案动态地更新ButtonFace
。同样适用于元素的color
属性,它被设置为相应的系统颜色ButtonText
。
看上去不错,但这也引出另一个新的概念,系统颜色(地址:https://drafts.csswg.org/css-color/#css-system-colors)。
有关于系统颜色这方面的不在这里详细阐述,如果你感兴趣的话可以阅读:
- 系统偏好设置的那些事儿
(地址:https://www.w3cplus.com/css/css-system-things.html) - Windows High Contrast Mode, Forced Colors Mode And CSS Custom Properties
(地址:https://www.smashingmagazine.com/2022/03/windows-high-contrast-colors-mode-css-custom-properties/) - Styling for Windows high contrast with new standards for forced colors
(地址:https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/) - Operating System and Browser Accessibility Display Modes
(地址:https://www.a11yproject.com/posts/operating-system-and-browser-accessibility-display-modes/)
- prefers-reduced-data
不是每个人都能幸运地拥有快速、可靠或无限的数据(流量)套餐。
你可能有过出差旅行的经历,也可能碰到了手机数据不够用,那么访问一个重图片的网站是很糟糕的(虽然说现在流量对于大家来说不是很大的事情,花钱总是能摆平的)。不过,一旦prefers-reduced-data
得到支持,那么这个头痛的事情就可以避免了,也可以帮用户省下一定的费用。因为,该特性可以让用户跳过大图或高分辨率的图像。
.image { background-image: url("images/heavy.jpg"); } @media (prefers-reduced-data: reduce) { .image { background-image: url("images/light.avif"); } }
当用户在设备上开启了“Low Data Mode”(低数据模式),会加载占流量更低的light.avif
图像,可以帮助iPhone上的应用程序减少网络数据的使用:
插个题外话,上面提到的这三个媒体查询特性主要是运用于 CSS 中,但它们还可以和 HTML 的 元素的
标签元素结合起来使用。可以根据用户对设备的偏好设置来选择不同的图片源:
<!-- 根据 prefers-color-scheme 为不同模式选择不同图片 --> <picture> <source srcset="dark.png" media="(prefers-color-scheme: dark)"> <source srcset="light.png" media="(prefers-color-scheme: light)"> <img src="light.png" alt="" /> </picture> <!-- 根据 prefers-reduced-motion 为用户呈现动图或静态图 --> <picture> <source srcset="animation.jpg" media="(prefers-reduced-motion: reduce)"> </source> <img srcset="animation.gif" alt="" /> </picture> <!-- 根据 prefers-reduced-data 为用户选择不同的图片 --> <picture> <source srcset="light.jpg" media="(prefers-reduced-data: reduce)" /> <img src="heavy.jpg" alt="" srcset="heavy@2x.jpg 2x" /> </picture>
- prefers-contrast
prefers-contrast
媒体查询主要用于检测用户是否要求系统增加或减少相邻颜色之间的对比度。比如一些喜欢阅读电子书的用户,在阅读与文本背景对比度相差不大的文本时会遇到困难,他们更喜欢较大的对比度,利于阅读。
比如像下面这个示例:
.contrast { background-color: #0958d8; color: #fff; } @media (prefers-contrast: high) { .contrast { background-color: #0a0db7; } }
- 其他与用户偏好有关的媒体特性
从W3C规范中不难发现,规范中提供了六个有关于用户偏好的媒体查询特性:
我们来看一个 forced-colors
的示例,该示例来自于 Eric 的 《Windows High Contrast Mode, Forced Colors Mode And CSS Custom Properties》一文:
Modal dialog with Forced Color mode tweaks @smashingmag CodePen (地址:https://codepen.io/smashingmag/pen/zYPVjPa) (地址:https://codepen.io/smashingmag) (地址:https://codepen.io/)
提取使用 forced-colors
的示例代码:
// SCSS .c-dialog__content { background-color: var(--dialog-color-background); box-shadow: 0 1rem 2rem 0 #00000099; outline: var(--dialog-border-width) solid var(--dialog-border-color); padding: var(--dialog-padding-outer); width: min(90vw, 38rem); z-index: 1; @media (forced-colors: active) { --dialog-border-width: var(--size-300); } }
在forced-colors
媒体查询特性中重新定义了 --dialog-border-width
的值。这样做的原因是一个非常有意思的调整。它把细的焦点框(outline
)变成了一个粗的。这样调整有助于显示模态框的外部边界,并传达它是漂浮在页面其他内容之上的信息。强制色彩模式删除了模态框的盒子阴影(box-shadow
),所以我们不能在这种专门的浏览模式下依赖这种视觉效果:
如果你对上面提到的媒体查询特性感兴趣的话,可以深入阅读下面这几篇文章:
- Media features
(地址:https://web.dev/learn/design/media-features/) - CSS媒体查询新特性
(地址:https://www.w3cplus.com/css/new-css-media-queries.html) - 系统偏好设置的那些事儿
(地址:https://www.w3cplus.com/css/css-system-things.html) - 图解CSS: CSS媒体查询
(地址:https://www.w3cplus.com/css/css-media-queries-guide.html)
▐ 响应容器的需求
CSS 的 媒体查询引发了一场响应式设计的革命,为开发者提供了一种方法来查询用户代理或设备环境的各个方面,比如视窗的大小或用户偏好来改变 Web 页面的风格。直到现在,媒体查询还做不到让元素的样式能根据一个最近的容器的大小来改变样式风格。也正因此,大家一直期待的容器查询来了。
很难想象,从基于页面的响应式设计(媒体查询)到基于容器的响应式设计(容器查询)的转变,对设计生态系统的发展会起到什么作用?
为了回答这个问题,接下来我们分几个方面来介绍,希望能给大家带来一定的思考,从而得到自己想要的答案。
- 容器查询的发展历程
正如我在《2022年的CSS》(地址:https://www.w3cplus.com/css/what-is-new-css-in-2022.html)一文中所提到的那样。一直以来,CSS 容器查询都是大家期待的一个特性,在这几年的CSS发展报告中,他一直位居第一:
自 2010 年 @Ethan Marcotte首次提出 响应式Web设计(RWD)(地址:https://alistapart.com/article/responsive-web-design/)的设计理念(概念),Web设计就进入现代Web布局时代。开发者可以根据 CSS 媒体查询特性 (通常是视窗宽度、媒体设备特性等)来为Web页面定制不同的表现形式,比如可以根据用户浏览内容的设备特性来呈现不同的布局、不同的字体大小和不同的图片等。
但对于 Web 设计师或Web开发者来说,在现代Web设计或布局中仍然缺少一特性,页面的设计不能够响应其容器的宽度(或其他特性)。也就是说,如果Web开发者能够根据容器宽度来改变UI样式,那就更好了。容器查询将在很大程度上帮助 Web 开发者更好的完成他们的工作,在为Web开发基于组件代码时,其遗漏(容器查询特性的缺失)是一个巨大的限制。
正因此,有关于容器查询的特性在社区中的探讨就没有停止过。