CSS Wrapped: 2023!
跳转到内容:
哇!2023 年是 CSS 的重要一年!
从 #Interop2023 到 CSS 和界面领域的许多新发布,这些发布都实现了开发者曾经认为在 Web 平台上不可能实现的功能。现在,所有现代浏览器都支持容器查询、子网格、:has()
选择器以及一系列新的颜色空间和函数。Chrome 支持仅使用 CSS 的滚动驱动型动画,并支持使用视图转场在网页视图之间流畅地呈现动画效果。最重要的是,我们还推出了许多新基元,以便提供更好的开发者体验,例如 CSS 嵌套和作用域样式。
今年真是非比寻常的一年!因此,在这一里程碑之年结束之际,我们想向浏览器开发者和网络社区致敬,感谢他们为此付出的辛勤努力。
架构基础知识
我们先来看看核心 CSS 语言和功能的更新。这些功能对于您编写和整理样式的方式至关重要,并可为开发者提供强大的功能。
三角函数
Chrome 111 添加了对三角函数 sin()
、cos()
、tan()
、asin()
、acos()
、atan()
和 atan2()
的支持,使其可在所有主要引擎中使用。这些函数对于动画和布局非常有用。例如,现在可以更轻松地在围绕选定中心的圆形上放置元素。
详细了解 CSS 中的三角函数。
复杂的“第 * 个”选择
浏览器支持
借助 :nth-child()
伪类选择器,您可以按索引选择 DOM 中的元素。使用 An+B
微语法,您可以精细控制要选择的元素。
默认情况下,:nth-*()
伪元素会将所有子元素考虑在内。从 Chrome 111 开始,您可以选择将选择器列表传入 :nth-child()
和 :nth-last-child()
。这样,您就可以在 An+B
执行操作之前预先过滤子项列表。
在下面的演示中,3n+1
逻辑通过使用 of .small
预先过滤掉小玩偶,仅应用于它们。使用下拉菜单动态更改所用的选择器。
详细了解复杂的“第 * 个”选择。
范围
Chrome 118 增加了对 @scope
的支持,这是一种 @ 规则,可让您将选择器范围与文档的特定子树进行匹配。借助作用域样式,您可以非常具体地选择要选择的元素,而无需编写过于具体的选择器或将其与 DOM 结构紧密耦合。
限定了范围的子树由范围根(上限)和可选的范围限制(下限)来定义。
@scope (.card) { … } /* scoping root */
@scope (.card) to (.card__content) { … } /* scoping root + scoping limit*/
放置在作用域块内的样式规则将仅定位到划出的子树中的元素。例如,以下作用域限定的样式规则仅定位到位于 .card
元素和 [data-component]
选择器匹配的任何嵌套组件之间的 <img>
元素。
@scope (.card) to ([data-component]) {
img { … }
}
在下面的演示中,由于应用的范围限制,轮播组件中的 <img>
元素不匹配。
范围演示屏幕截图
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。
排版
2023 年,Web 排版发生了一些重大更新。text-wrap
属性是一项非常实用的渐进式增强功能。此属性可让您调整排版布局,由浏览器编写,无需其他脚本。告别繁琐的排版,迎接更可预测的排版!
Initial-letter
initial-letter
属性是 Chrome 110 年初推出的一项小巧但功能强大的 CSS 功能,可用于设置首字母的放置样式。您可以将字母放置到落地或凸起状态。该属性接受两个参数:第一个表示字母落入相应段落的深度,第二个表示字母上方字母升高多少。您甚至可以将这两种方法结合使用,如以下演示所示。
首字母屏幕截图
首字母演示
详细了解首字母。
text-wrap: Balance and Pretty
作为开发者,您不知道标题或段落的最终大小、字号甚至语言。浏览器中包含处理文本换行效果所需的所有变量,这些变量可以有效且美观地处理文本换行。由于浏览器确实知道字体大小、语言和分配区域等所有因素,因此非常适合处理高级且高质量的文本布局。
这就是两种新的文本换行技巧,一种称为 balance
,另一种称为 pretty
。balance
值旨在创建和谐的文本块,而 pretty
则旨在防止孤立内容并确保断字能力正常。这两项任务传统上都是手动完成的,现在能够交给浏览器来完成,并且适用于任何翻译语言,这真是太棒了。
文本换行屏幕录制
文本换行实时演示
详细了解 text-wrap: balance。
颜色
2023 年是该网络平台色彩的一年。借助支持动态配色的新颜色空间和函数,您可以随心所欲地为用户打造鲜艳丰富的主题,并使其可自定义!
高清色彩空间(色彩级别 4)
从硬件到软件,从 CSS 到闪烁的灯光,计算机需要付出大量努力,才能尽可能准确地呈现人眼可见的颜色。2023 年,我们将推出新颜色、更多颜色、新的颜色空间、颜色函数和新功能。
CSS 和颜色现在可以:
- 检查用户屏幕硬件是否支持广色域 HDR 颜色。
- 检查用户的浏览器能否理解 Oklch 或 Display P3 等颜色语法。
- 以 Oklab、Oklch、HWB、Display P3、Rec.2020、XYZ 等格式指定 HDR 颜色。
- 使用 HDR 颜色创建渐变,
- 在其他色彩空间中插值渐变。
- 使用 color-mix()
混合颜色。
- 使用相对颜色语法创建颜色变体。
Color 4 屏幕录制
Color 4 演示
详细了解 Color 4 和色彩空间。
color-mix 函数
混合颜色是一项经典任务,在 2023 年,CSS 也能执行此任务。您不仅可以将白色或黑色混合到颜色中,还可以混合透明度,并且可以在您选择的任何色彩空间中执行所有这些操作。它既是一项基本色彩功能,也是一项高级色彩功能。
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)
)。
样式查询屏幕截图
样式查询演示
这听起来与在 CSS 中使用类名称类似,但样式查询有一些优势。首先,通过样式查询,您可以根据伪状态的需要更新 CSS 中的值。此外,在未来的实现版本中,您将能够查询值范围以确定应用的样式(例如 style(60 <= --weather <= 70)
),以及基于“属性-值”对(例如 style(font-style: italic)
)的样式。
详细了解如何使用样式查询。
:has() 选择器
近 20 年来,开发者一直在要求 CSS 中提供“父级选择器”。现在,借助 Chrome 105 中随附的 :has()
选择器,即可实现这一点。例如,使用 .card:has(img.hero)
将选择具有主推图片作为子元素的 .card
元素。
:has() 演示屏幕截图
:has() 实时演示
由于 :has()
接受相对选择器列表作为参数,因此您可以选择的不仅仅是父元素。使用各种 CSS 组合符,不仅可以向上遍历 DOM 树,还可以进行横向选择。例如,li:has(+ li:hover)
会选择当前悬停的 <li>
元素之前的 <li>
元素。
:has() 抓屏
:has() 演示
详细了解 CSS :has()
选择器。
更新媒体查询
借助 update
媒体查询,您可以根据设备的刷新率调整界面。该功能可以报告值 fast
、slow
或 none
,该值与不同设备的功能相关。
您设计的大多数设备都有较快的刷新频率。这包括桌面设备和大多数移动设备。电子阅读器和低功耗付款系统等设备的刷新率可能较慢。知道设备无法处理动画或频繁更新,意味着您可以节省电量或避免视图更新出现故障。
更新屏幕录制
更新演示
详细了解 @media(更新)。
使用脚本编写媒体查询
脚本媒体查询可用于检查 JavaScript 是否可用。这非常适合渐进式增强。在此媒体查询之前,检测 JavaScript 是否可用的方法是将 nojs
类放入 HTML 中,然后使用 JavaScript 将其移除。由于 CSS 现在可以检测 JavaScript 并相应地进行调整,因此可以移除这些脚本。
如需了解如何在网页上启用和停用 JavaScript 以便通过 Chrome DevTools 进行测试,请点击此处。
脚本屏幕演示
脚本演示
假设您要对网站上的主题进行切换,由于没有可用的 JavaScript,脚本媒体查询可以帮助您根据系统偏好设置进行切换。或者,考虑一下开关组件:如果 JavaScript 可用,则可以使用手势滑动开关,而不仅仅是开启和关闭开关。如果可使用脚本,则有很多机会升级用户体验;如果脚本已停用,则可以提供有意义的基础体验。
详细了解脚本。
低透明度媒体查询
不透明的界面可能会导致头痛,或者对各种类型的视觉缺陷造成视觉障碍。因此,Windows、macOS 和 iOS 都设有系统偏好设置,这类偏好设置可以降低或消除界面的透明度。适用于 prefers-reduced-transparency
的此媒体查询与其他偏好媒体查询非常契合,可让您在发挥创意的同时,根据用户进行调整。
“降低透明度”屏幕录制
降低透明度演示
在某些情况下,您可以提供一种替代布局,其中不会有内容叠加在其他内容上。在其他情况下,可以将颜色的不透明度调整为不透明或几乎不透明。以下博文提供了更多鼓舞人心的演示,这些演示可以适应用户偏好,如果您想知道此媒体查询何时具有价值,不妨看看他们。
交互
互动是数字体验的基石。它有助于用户了解自己点击了什么,以及自己在虚拟空间中的所在位置。今年,我们发布了许多激动人心的功能,这些功能简化了交互的编写和实现,从而实现顺畅的用户体验历程和更精细的网络体验。
视图过渡
视图转换对网页的用户体验有很大影响。借助 View Transitions API,您可以在单页应用的两种页面状态之间创建视觉转场。这些转场效果可以是整个页面的转场效果,也可以是页面上较小的转场效果,例如向列表中添加或移除新项。
View Transitions API 的核心是 document.startViewTranstion
函数。传入一个函数来将 DOM 更新为新状态,该 API 将为您处理一切。它通过拍摄前后对比的快照,然后在两者之间进行过渡来实现此目的。您可以使用 CSS 来控制要拍摄的内容,并视需要自定义这些快照的动画方式。
VT 抓屏
VT 演示
适用于单页应用的 View Transitions API 已在 Chrome 111 中发布。详细了解视图转换。
线性缓动函数
浏览器支持
不要被此函数的名称欺骗到。借助 linear()
函数(请勿与 linear
关键字混淆),您可以简单地创建复杂的缓动函数,但代价是会丢失一些精度。
在 Chrome 113 中推出 linear()
之前,您无法在 CSS 中创建弹跳或弹簧效果。借助 linear()
,您可以将这些缓动效果简化为一系列点,然后在这些点之间进行线性插值,以近似地实现这些缓动效果。
线性缓动抓屏
线性缓动演示
滚动结束
许多界面包含滚动交互,有时界面需要同步与当前滚动位置相关的信息,或根据当前状态提取数据。在 scrollend
事件之前,您必须使用不准确的超时方法,该方法可能会在用户的手指仍在屏幕上时触发。借助 scrollend
事件,您可以获得恰到好处的滚动结束事件,以了解用户是否仍在进行手势中间。
滚动屏幕抓屏
Scrollend 演示
这对浏览器来说非常重要,因为 JavaScript 无法跟踪滚动期间手指在屏幕上的存在情况,因为系统根本无法获取相关信息。现在,您可以删除不准确的滚动结束尝试代码块,并将其替换为浏览器拥有的高精度事件。
详细了解 scrollend。
滚动条驱动的动画
滚动条驱动的动画是 Chrome 115 中推出的一项令人兴奋的功能。借助这些方法,您可以使用现有的 CSS 动画或使用 Web 动画 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
便可附加到它,从而使其具有更广泛的范围。完成后,该共享父级的任何子级都可以使用该名称的时间轴。
演示版抓屏
实时演示
详细了解 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
之间进行动画效果。此规则提供了一种为元素设置“打开前”样式的途径,浏览器可以在元素在页面上打开之前查找此样式。这对于进入动画以及在弹出式窗口或对话框等元素中进行动画处理非常有用。当您创建元素并希望为其添加进入动画效果时,此属性也非常有用。以下示例将 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
键或双击即可关闭弹出式窗口并返回焦点。 - 无障碍组件绑定。从语义上将弹出式窗口元素连接到弹出式窗口触发器。
弹出式窗口抓屏
弹出式窗口实时演示
选择中的水平规则
今年,Chrome 和 Safari 中又推出了一项 HTML 小更改,即在 <select>
元素中添加水平规则元素(<hr>
标记),以帮助直观地拆分内容。以前,将 <hr>
标记放在 select 中根本无法呈现。不过,今年 Safari 和 Chrome 都支持此功能,可更好地分隔 <select>
元素中的内容。
选择屏幕截图
选择“实时演示”
详细了解如何使用“选择时间”选项
:用户有效和无效的伪类
:user-valid
和 :user-invalid
今年在所有浏览器中均已稳定运行,其行为与 :valid
和 :invalid
伪类类似,但只有在用户与输入内容进行了显著互动后,才会与表单控件匹配。必填且空的表单控件将与 :invalid
匹配,即使用户尚未开始与网页互动也是如此。在用户更改输入并将其留在无效状态之前,同一控件不会与 :user-invalid
匹配。
有了这些新的选择器,您无需再编写有状态的代码来跟踪用户更改的输入。
:user-* 屏幕录制
:user-* 实时演示
详细了解如何使用 user-* 表单验证伪元素。
专属手风琴式折叠
浏览器支持
网站上常见的界面模式是手风琴组件。如需实现此模式,您需要组合几个 <details>
元素,通常以可视化方式将它们分组,以表明它们属于同一类。
Chrome 120 新增了对 <details>
元素上的 name
属性的支持。使用此属性时,具有相同 name
值的多个 <details>
元素会组成一个语义群组。组中最多只能有一个元素处于打开状态:当您打开组中的某个 <details>
元素时,之前打开的那个元素将自动关闭。这种类型的折叠动作条被称为独占折叠动作条。
属于独占折叠菜单的 <details>
元素不一定是同级兄弟元素。它们可以散布在文档中。
过去几年,CSS 经历了一次复兴,尤其是在 2023 年。如果您刚开始接触 CSS,或者只是想复习一下基础知识,请查看我们的免费 Learn CSS 课程以及 web.dev 上提供的其他免费课程。
祝您节日快乐,并希望您能尽快将这些出色的新 CSS 和界面功能融入到您的工作中!
Chrome 界面开发者关系团队