CSS 封装:2023 年!
跳转至内容:
哇!2023 年对 CSS 来说是硕果累累的一年!
从 #Interop2023 到 CSS 和界面领域的许多新登陆,让开发者曾经认为在网络平台上不可能具备一些功能。现在,所有现代浏览器都支持容器查询、subgrid、:has()
选择器以及大量新的颜色空间和函数。我们在 Chrome 中支持仅限 CSS 的滚动驱动动画,并支持通过视图转换在网页视图之间流畅地呈现动画效果。最重要的是,这里有很多新的基元可用于改善开发者体验,例如 CSS 嵌套和限定作用域样式。
今年真是非比寻常的一年!在这一具有里程碑意义的一年结束时,我们要祝贺和感谢浏览器开发者和网络社区为实现这一切而付出的巨大努力。
建筑基础
首先,我们对核心 CSS 语言和功能进行了更新。这些功能是您编写和组织样式的基础,并且可以为开发者提供强大的功能。
三角函数
Chrome 111 添加了对三角函数 (sin()
、cos()
、tan()
、asin()
、acos()
、atan()
和 atan2()
) 的支持,使其可在所有主要引擎中使用。这些函数对于动画和布局目的来说非常方便。例如,现在可以更轻松地在围绕选定中心的圆形上放置元素。
详细了解 CSS 中的三角函数。
复杂的 nth-* 选择
浏览器支持
- 111
- 111
- 113
- 9
借助 :nth-child()
伪类选择器,您可以按索引选择 DOM 中的元素。使用 An+B
微语法,您可以精细地控制要选择哪些元素。
默认情况下,:nth-*()
伪代码会将所有子元素都考虑在内。从 Chrome 111 开始,您可以选择将选择器列表传递到 :nth-child()
和 :nth-last-child()
。这样,您就可以在 An+B
执行操作之前预先过滤子项列表。
在下面的演示中,3n+1
逻辑通过使用 of .small
预先过滤掉小玩偶,仅应用于它们。使用下拉菜单动态更改所使用的选择器。
详细了解复杂的 nth-* 选择。
范围
Chrome 118 添加了对 @scope
的支持,这是一种 @ 规则,可让您将选择器的范围与文档的特定子树进行匹配。借助作用域样式设置,您可以非常具体地指定选择哪些元素,而无需编写过于具体的选择器或将其与 DOM 结构紧密耦合。
限定了范围的子树由范围根(上限)和可选的范围限制(下限)来定义。
@scope (.card) { … } /* scoping root */
@scope (.card) to (.card__content) { … } /* scoping root + scoping limit*/
放置在作用域块内的样式规则只会定位剥离的子树中的元素。例如,以下限定了范围的样式规则仅定位到位于 .card
元素之间的 <img>
元素以及与 [data-component]
选择器匹配的任何嵌套组件。
@scope (.card) to ([data-component]) {
img { … }
}
在下面的演示中,由于应用的范围限制,轮播组件中的 <img>
元素不匹配。
范围演示屏幕截图
![@scope 演示的参考屏幕截图 @scope 演示的参考屏幕截图](https://developer.chrome.google.cn/static/blog/css-wrapped-2023/image/at-scope.png?authuser=5&hl=fi)
范围实时演示
@scope
演示如需详细了解 @scope
,请参阅“如何使用 @scope
限制选择器的覆盖范围”一文。在本文中,您将了解 :scope
选择器、特异性的处理方式、无前序作用域,以及 @scope
对级联的影响。
嵌套
在嵌套之前,每个选择器都需要单独进行明确声明。这会导致重复、批量提供样式表以及零散的创作体验。现在,选择器可以用分组的相关样式规则继续。
dl {
/* dt styles */
dt {
/* dl dt styles */
}
dd {
/* dl dd styles */
}
}
/* same as */
dt {
/* dt styles */
}
dl dt {
/* dl dt styles */
}
dl dd {
/* dl dd styles */
}
嵌套抓屏
经验积累现场演示
嵌套可以减少样式表的重量,减少重复使用选择器的开销,并集中组件样式。语法最初发布时存在一项限制,即需要在很多地方使用 &
,但之后又通过嵌套式语法更新取消了该语法。
详细了解嵌套。
子网格
借助 CSS subgrid
,您可以创建更复杂的网格,并且可以更好地在子布局之间对齐。它允许另一个网格内的网格通过使用 subgrid
作为网格行或列的值,将外部网格的行和列作为自己的行和列。
子网格抓屏
Subgrid 实时演示
subgrid 在将同级元素与彼此的动态内容对齐时特别有用。这样,文案人员、用户体验文案人员和翻译人员就不必再尝试撰写“适合”的项目文案添加到布局中使用 subgrid,可以根据内容调整布局。
详细了解 subgrid。
排版
2023 年,网页排版出现了几项重要更新。text-wrap
属性是一个特别实用的渐进式增强功能。此属性可让您调整排版布局,由浏览器编写,无需其他脚本。告别繁琐的排版,迎接更可预测的排版!
首字母
今年年初时,Chrome 110 会发布 initial-letter
属性,这是一项小而强大的 CSS 功能,用于设置初始字母的样式设置。您可以将字母放置到落地或凸起状态。该属性接受两个参数:第一个参数表示字母落入相应段落的深度,第二个参数表示字母上方字母升高多少。您甚至可以将两者结合使用,如以下演示所示。
首字母大写的屏幕截图
![首字母缩写演示的屏幕截图](https://developer.chrome.google.cn/static/blog/css-wrapped-2023/image/initial-letter.png?authuser=5&hl=fi)
首字母字母演示
::first-letter
伪元素的 initial-letter
值,观察其偏移情况。详细了解首字母。
text-wrap: balance and pretty
作为开发者,您并不知道标题或段落的最终大小、字体大小,甚至是语言。有效且美观地处理文本换行所需的所有变量均位于浏览器中。由于浏览器确实了解所有因素(例如字体大小、语言和分配区域),因此非常适合处理高级和高质量的文本布局。
这就是两种新的文本换行技巧,一种称为 balance
,另一种称为 pretty
。balance
值旨在创建协调一致的文本块,而 pretty
则旨在防止孤立内容并确保断字能力正常。这两项任务历来都是手动完成的,如果能将工作交给浏览器,让它支持任何翻译语言,将会非常棒。
屏幕自动换行
文本换行实时演示
balance
和 pretty
对标题和段落的效果。不妨尝试将演示翻译成其他语言!详细了解文本换行:余额。
颜色
2023 年是该网络平台色彩的一年。有了支持动态配色主题的全新颜色空间和函数,您不仅可以创建用户应有的生动鲜活的主题,还能使这些主题进行自定义,让您尽情享受主题创作的乐趣!
高清色彩空间(颜色级别 4)
从硬件到软件,从 CSS 到闪烁的灯光;我们的计算机需要完成大量工作,才能尝试呈现出人眼所见的完美颜色。2023 年,我们推出了新的颜色、更多的颜色、新的颜色空间、颜色功能和新功能。
CSS 和颜色现在可以:
- 检查用户屏幕硬件是否支持广色域 HDR 颜色。
- 检查用户的浏览器能否理解 Oklch 或 Display P3 等颜色语法。
- 在 Oklab、Oklch、HWB、Display P3、Rec.2020、XYZ 等中指定 HDR 颜色。
- 利用 HDR 色彩实现渐变效果,
- 在替代颜色空间中插入渐变。
- 使用 color-mix()
混合颜色。
- 使用相对颜色语法创建颜色变体。
颜色 4 抓屏
颜色 4 演示
详细了解颜色 4 和颜色空间。
color-mix 函数
混合颜色是一项传统任务,而 CSS 在 2023 年也可以做到。您不仅可以将白色或黑色混合到某种颜色中,还可以将透明度加入到某个颜色中,并且可以在您选择的任何颜色空间中完成所有这些操作。它既是基本色彩功能,又是高级色彩功能。
color-mix() 抓屏
color-mix() 演示
您可以将 color-mix()
视为渐变中的一个时刻。如果渐变显示了从蓝色变为白色所需的全部步骤,color-mix()
则只显示了一步。一旦您开始将颜色空间考虑在内,并了解混合颜色空间与结果之间的差异,情况就会更深刻。
详细了解 color-mix()。
相对颜色语法
相对颜色语法 (RCS) 是 color-mix()
的补充方法,用于创建颜色变体。它比 color-mix() 功能略强一些,但也是一种不同的颜色处理策略。color-mix()
可能会混合白色来调亮颜色,其中 RCS 会授予对亮度通道的精确访问权限,并能够在通道上使用 calc()
以编程方式降低或增加亮度。
RCS 抓屏
RCS 现场演示
借助 RCS,您可以对颜色执行相对和绝对操作。相对变化是指获取饱和度或亮度的当前值,并使用 calc()
进行修改。绝对更改是指将通道值替换为全新的值,例如将不透明度设置为 50%。此语法为您提供了有意义的主题设置工具,以及时间变体等。
详细了解相对颜色语法。
自适应设计
自适应设计发展于 2023 年。这一具有开创性的一年推出了一些新功能,彻底改变了我们构建响应式 Web 体验的方式,并开创了基于组件的响应式设计的新模式。将容器查询和 :has()
结合使用后,组件就可以根据父级的大小以及任何子级的存在或状态来打造自适应样式和逻辑样式。这意味着,您最终可以分离页面级布局与组件级布局,只需编写一次逻辑,即可在所有位置使用您的组件!
大小容器查询
容器查询支持查询页面内的父元素,而不是使用视口的全局尺寸信息来应用 CSS 样式。这意味着,组件可以在多个布局和多个视图中以动态方式进行样式设置。在今年的情人节(2 月 14 日)当天,容器大小查询在所有现代浏览器中都稳定了。
如需使用此功能,请先在要查询的元素上设置包含关系,然后与媒体查询类似,将 @container
与尺寸参数结合使用以应用样式。除了容器查询,您还可以获取容器查询大小。在下面的演示中,容器查询大小 cqi
(表示内嵌容器的大小)用于调整卡片标题的大小。
@container 抓屏
@container 演示
详细了解如何使用容器查询。
样式容器查询
在 Chrome 111 中,样式查询已部分实现。目前,通过样式查询,您可以在使用 @container style()
时查询父元素上自定义属性的值。例如,查询某个自定义属性值是否存在,或者设置为某个值(如 @container style(--rain: true)
)。
样式查询屏幕截图
![样式容器查询天气卡片的演示屏幕截图](https://developer.chrome.google.cn/static/blog/css-wrapped-2023/image/stylecq.png?authuser=5&hl=fi)
样式查询演示
虽然这听起来类似于在 CSS 中使用类名称,但样式查询具有一些优势。首先,通过样式查询,您可以根据伪状态的需要更新 CSS 中的值。此外,在未来的实现版本中,您将能够查询值范围以确定应用的样式(例如 style(60 <= --weather <= 70)
),以及基于“属性-值”对(例如 style(font-style: italic)
)的样式。
详细了解如何使用样式查询。
:has() 选择器
近 20 年来,开发者一直希望开发者使用“父级选择器”。现在,借助 Chrome 105 中随附的 :has()
选择器,可以实现这一目的。例如,使用 .card:has(img.hero)
将选择以主打图片作为子元素的 .card
元素。
:has() 演示屏幕截图
![:has() 演示的参考屏幕截图 :has() 演示的参考屏幕截图](https://developer.chrome.google.cn/static/blog/css-wrapped-2023/image/has-demo-1.png?authuser=5&hl=fi)
:has() 现场演示
:has()
演示:无图片/带图片的卡片由于 :has()
接受相对选择器列表作为其参数,因此您可以选择的不仅仅是父元素。使用各种 CSS 组合器,您不仅可以向上访问 DOM 树,还可以进行横向选择。例如,li:has(+ li:hover)
将选择当前悬停的 <li>
元素之前的 <li>
元素。
:has() 抓屏
:has() 演示
:has()
演示:Dock详细了解 CSS :has()
选择器。
更新媒体查询
借助 update
媒体查询,您可以根据设备的刷新率调整界面。该功能可以报告与不同设备的功能相关的 fast
、slow
或 none
值。
您设计的大多数设备都有较快的刷新频率。这包括桌面设备和大多数移动设备。电子阅读器和设备(例如低功耗付款系统)的刷新频率可能较慢。知道设备无法处理动画或频繁更新,意味着您可以节省电量消耗或减少错误的视图更新。
更新抓屏
更新演示
详细了解 @media(更新)。
脚本媒体查询
脚本媒体查询可用于检查 JavaScript 是否可用。这对于渐进式增强非常有用。在发布此媒体查询之前,检测 JavaScript 是否可用的策略是在 HTML 中放置一个 nojs
类,并使用 JavaScript 将其移除。由于 CSS 现在能够检测 JavaScript 并进行相应调整,因此可以移除这些脚本。
请点击此处,了解如何通过 Chrome 开发者工具在网页上启用和停用 JavaScript 以进行测试。
脚本抓屏
脚本演示
假设某个网站上的主题切换,由于没有 JavaScript 可用,因此脚本媒体查询有助于使该切换针对系统偏好设置发挥作用。或者考虑使用一个开关组件 - 如果支持 JavaScript,那么可以通过手势来滑动开关,而不只是开/关。如果可以使用脚本,这是提升用户体验的绝佳机会;如果停用脚本,还可以提供有意义的基础体验。
详细了解脚本。
低透明度媒体查询
非不透明界面可能会引起头痛或因各种类型的视觉缺陷而造成视觉疲劳。因此,Windows、macOS 和 iOS 都设有系统偏好设置,这类偏好设置可以降低或消除界面的透明度。“prefers-reduced-transparency
”的这项媒体查询与其他偏好的媒体查询完美契合,让您能够发挥创意,同时针对用户做出调整。
降低透明度抓屏
降低透明度演示
在某些情况下,您可以提供备用布局,让内容不叠加在其他内容上。在其他情况下,可将颜色的不透明度调整为不透明或近乎不透明。以下博文提供了更多鼓舞人心的演示,这些演示可以适应用户偏好,如果您想知道此媒体查询何时具有价值,不妨看看他们。
交互
互动是数字体验的基石。它可以帮助用户获取有关所点击的内容以及他们在虚拟空间中所处的位置的反馈。今年,我们发布了许多激动人心的功能,这些功能简化了交互的编写和实现,从而实现顺畅的用户体验历程和更精细的网络体验。
视图过渡
视图过渡会对网页的用户体验产生巨大影响。借助 View Transitions API,您可以在单页应用的两种页面状态之间创建视觉转场。这些过渡可以是整页过渡,也可以是页面上的较小内容(例如向列表中添加或移除新项)。
View Transitions API 的核心是 document.startViewTranstion
函数。传入一个函数来将 DOM 更新为新状态,该 API 将为您处理一切。为此,它会拍摄前后的快照,然后在两者之间转换。您可以使用 CSS 来控制要拍摄的内容,并视需要自定义这些快照的动画方式。
VT 抓屏
VT 演示
Chrome 111 中随附的适用于单页应用的 View Transitions API。详细了解视图过渡。
线性加/减速函数
浏览器支持
- 113
- 113
- 112
- 17.2
不要被此函数的名称欺骗到。借助 linear()
函数(不要与 linear
关键字混淆),您可以通过简单的方式创建复杂的加/减速函数,但会牺牲部分精度。
在 Chrome 113 中推出 linear()
之前,您无法在 CSS 中创建弹跳或弹簧效果。得益于 linear()
,可以将它们简化为一系列点,然后在这些点之间以线性方式插值来近似计算这些加/减速效果。
linear()
函数使用这些点并在它们之间线性插值。线性加/减速抓屏
线性加/减速演示
linear()
演示滚动结束
许多界面包含滚动交互,有时界面需要同步与当前滚动位置相关的信息,或根据当前状态提取数据。在 scrollend
事件发生之前,您必须使用不准确的超时方法,该方法可能会在用户的手指停留在屏幕上时触发。借助 scrollend
事件,您可以获得恰到好处的滚动结束事件,以了解用户是否仍在进行手势中间。
滚动屏幕抓屏
滚动演示
这对浏览器来说非常重要,因为在滚动过程中 JavaScript 无法跟踪手指在屏幕上的出现,导致信息不可用。现在,您可以删除大量不准确的滚动结束尝试代码,并将其替换为浏览器拥有的高精度事件。
详细了解滚动。
滚动驱动的动画
滚动条驱动的动画是 Chrome 115 中提供的一项激动人心的功能。借助这些属性,您可以提取现有的 CSS 动画或使用 Web Animations API 构建的动画,并将其与滚动条的滚动偏移值相结合。当您在水平滚动条中上下滚动时,关联的动画会在直接响应时前后拖动动画。
您可以使用 ScrollTimeline 来跟踪滚动条的总体进度,如以下演示所示。当您滚动到页面底部时,文字会逐字显示。
SDA 抓屏
SDA 演示
借助 ViewTimeline,您可以在元素经过滚动端口时对其进行跟踪。其工作原理与 IntersectionObserver 跟踪元素的方式类似。在下面的演示中,每张图片从进入滚动端口的那一刻开始,一直显示到中心位置。
SDA 演示抓屏
SDA 现场演示
由于滚动驱动的动画可与 CSS 动画和 Web Animations API 配合使用,因此您可以从这些 API 带来的所有优势中受益。这包括让这些动画在主线程之外运行的功能。现在,您只需再添加几行代码,即可实现由滚动驱动的平滑动画,使动画在主线程之外运行。有没有什么不喜欢呢?
如需详细了解滚动条驱动的动画,请参阅本文了解所有详情或访问 scroll-driven-animations.style,其中包含许多演示。
延迟时间轴附件
通过 CSS 应用滚动驱动的动画时,用于查找控制滚动条的查找机制始终会遍历 DOM 树,使其仅限于滚动祖先实体。然而,很多情况下,需要设置动画效果的元素并非滚动条的子项,而是位于完全不同的子树中的元素。
若要允许动画元素查找非祖先实体的已命名滚动时间轴,请在共享父项上使用 timeline-scope
属性。这样一来,便可将已定义的 scroll-timeline
或具有该名称的 view-timeline
附加到其中,从而扩大范围。设置完毕后,该共享父级的任何子级均可使用具有该名称的时间轴。
![DOM 子树的可视化效果,在共享的父项上使用时间轴范围 DOM 子树的可视化效果,在共享的父项上使用时间轴范围](https://developer.chrome.google.cn/static/blog/css-wrapped-2023/image/defferedtimeline.png?authuser=5&hl=fi)
timeline-scope
后,使用滚动条作为其 animation-timeline
的元素可以找到滚动条上声明的 scroll-timeline
演示抓屏
实时演示
详细了解timeline-scope
。
离散属性动画
2023 年的另一项新功能是为离散动画添加动画效果,例如为与 display: none
之间的进出添加动画效果。从 Chrome 116 开始,您可以在关键帧规则中使用 display
和 content-visibility
。您还可以在 50% 点(而不是 0% 点)转换任何离散属性。这可以通过使用 allow-discrete
关键字的 transition-behavior
属性实现,或在 transition
属性中作为简写形式实现。
离散动画。抓屏
离散动画。演示
详细了解转换离散动画。
@starting-style
@starting-style
CSS 规则基于新的 Web 功能构建,用于在 display: none
之间添加动画效果。此规则提供了一种为元素设置“before-open”的方法。在网页上打开元素之前浏览器可以查找的样式。这对于条目动画以及为弹出式窗口或对话框等元素添加动画效果非常有用。每当您创建元素并希望为其添加动画效果时,它也非常有用。以下示例将 popover
属性(参见下一部分)以动画形式呈现到视图中,并从视口外部平滑地进入顶层。
@starting-style 抓屏
@starting-style 演示
详细了解 @starting-style 和其他进入动画。
叠加层
可以在过渡中添加新的 CSS overlay
属性,以便具有顶层样式的元素(例如 popover
和 dialog
)能够顺畅地从顶层呈现动画效果。如果没有为叠加层添加过渡效果,您的元素会立即恢复为对元素进行剪裁、转换和覆盖,而且您不会看到过渡效果。同样,在添加到顶层元素时,overlay
可让 ::backdrop
平滑地向外呈现动画效果。
叠加抓屏
重叠式广告实时演示
详细了解叠加层和其他退出动画。
组件
2023 年是样式与 HTML 组件交融的一年,在此期间,popover
已经落地,我们在锚点定位和样式下拉菜单的未来发展方面做了大量工作。借助这些组件,您可以更轻松地构建常见的界面模式,而无需依赖其他库或每次从头开始构建您自己的状态管理系统。
弹出式窗口
Popover API 可帮助您构建位于页面其余部分之上的元素。包括菜单、选项和提示。如需创建简单的弹出式窗口,您可以向弹出的元素添加 popover
属性和 id
,然后使用 popovertarget="my-popover"
将其 id
属性与调用按钮相关联。Popover API 支持:
- 提升到顶层。弹出式窗口将会显示在网页其余部分上方的一个独立层中,这样您就不必调整 Z-index 了。
- 轻关闭功能。点击弹出式窗口区域以外的位置,即可关闭弹出式窗口并返回焦点。
- 默认焦点管理。打开弹出式窗口后,下一个标签页就会停止在弹出式窗口内。
- 无障碍键盘绑定。按
esc
键或切换两次将关闭弹出式窗口并返回焦点。 - 可访问的组件绑定。从语义上将弹出式窗口元素连接到弹出式窗口触发器。
弹出式窗口抓屏
Popover 现场演示
select 中的水平规则
今年,Chrome 和 Safari 中又推出了一项 HTML 小更改,即在 <select>
元素中添加水平规则元素(<hr>
标记),以帮助直观地拆分内容。以前,将 <hr>
标记放在 select 中根本无法呈现。但今年,Safari 和 Chrome 都支持此功能,这样可以更好地分离 <select>
元素中的内容。
选择“屏幕截图”
![Chrome 中具有浅色和深色主题的 hr 的屏幕截图](https://developer.chrome.google.cn/static/blog/css-wrapped-2023/image/hrselect.jpg?authuser=5&hl=fi)
选择现场演示
详细了解如何使用“选择时间”选项
:用户有效和无效的伪类
今年,:user-valid
和 :user-invalid
在所有浏览器中都很稳定,其行为与 :valid
和 :invalid
伪类类似,但仅在用户与输入进行大量互动后才会匹配表单控件。必需且空白的表单控件将与 :invalid
匹配,即使用户尚未开始与页面互动也是如此。在用户更改输入并将其置于无效状态之前,同一控件不会匹配 :user-invalid
。
有了这些新的选择器,就不再需要编写有状态代码来跟踪用户更改的输入。
:user-* 抓屏
:user-* 现场演示
详细了解如何使用 user-* 表单验证伪元素。
独家手风琴式折叠
浏览器支持
- 120
- 120
- x
- 17.2
Web 上常见的界面模式是手风琴式组件。如需实现此模式,您需要组合几个 <details>
元素,通常以可视化方式将它们分组,以表明它们属于同一类。
Chrome 120 中的新功能支持在 <details>
元素中使用 name
属性。使用此属性时,具有相同 name
值的多个 <details>
元素形成语义组。组中最多只能有一个元素处于打开状态:当您打开组中的某个 <details>
元素时,之前打开的那个元素将自动关闭。此类手风琴式折叠称为独占手风琴式折叠。
独占手风琴中的 <details>
元素不一定要是同级元素。它们可以分散在文档中。
CSS 在过去几年里经历了如此多的复兴,尤其是在 2023 年。如果您是 CSS 新手或只想复习一下基础知识,请访问 web.dev 查看我们免费的学习 CSS 课程以及提供的其他免费课程。
祝您节日快乐,希望您有机会尽快在工作中融入一些出色的全新 CSS 和界面功能!
⇾ Chrome 界面开发团队