CSS Wrapped:2023 年!
跳转到内容:
哇!2023 年是 CSS 发展史上非常重要的一年!
从 #Interop2023 到 CSS 和界面领域中的许多新功能,这些功能使开发者能够在 Web 平台上实现他们曾经认为不可能实现的功能。现在,所有现代浏览器都支持容器查询、子网格、:has()
选择器以及大量新的颜色空间和函数。我们在 Chrome 中支持纯 CSS 滚动驱动的动画,并支持使用视图过渡在网页视图之间平滑地添加动画效果。最重要的是,我们还推出了许多新的基元,以改善开发者体验,例如 CSS 嵌套和作用域样式。
今年真是非比寻常的一年!因此,我们想在这一里程碑式的一年结束之际,向浏览器开发者和 Web 社区致敬,感谢他们为实现这一切所付出的辛勤努力。
架构基础知识
我们先来看看核心 CSS 语言和功能方面的更新。这些功能是您创作和整理样式的基础,可为开发者带来强大的功能。
三角函数
Chrome 111 新增了对三角函数 sin()
、cos()
、tan()
、asin()
、acos()
、atan()
和 atan2()
的支持,从而使这些函数可在所有主要引擎中使用。这些函数在动画和布局方面非常有用。例如,现在可以更轻松地在围绕所选中心的圆圈上布局元素。
详细了解 CSS 中的三角函数。
复杂的 nth-* 选择器
Browser Support
借助 :nth-child()
伪类选择器,可以按索引选择 DOM 中的元素。借助 An+B
微语法,您可以精细地控制要选择的元素。
默认情况下,:nth-*()
伪类会考虑所有子元素。从 Chrome 111 开始,您可以选择性地将选择器列表传递给 :nth-child()
和 :nth-last-child()
。这样,您就可以在 An+B
执行操作之前预先过滤子级列表。
在以下演示中,3n+1
逻辑仅应用于小娃娃,方法是使用 of .small
预先过滤掉其他娃娃。使用下拉菜单动态更改所用的选择器。
详细了解复杂的 nth-* 选择器。
范围
Chrome 118 新增了对 @scope
的支持,该 at-rule 可让您将选择器匹配范围限定为文档的特定子树。借助作用域样式,您可以非常具体地选择元素,而无需编写过于具体的选择器或将它们紧密耦合到 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
选择器、特异性的处理方式、无序言范围,以及级联如何受到 @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
作为网格行或列的值,采用外部网格的行和列作为自己的行和列。
子网格屏幕演示
子网格实时演示
子网格对于使同级元素彼此对齐动态内容特别有用。这样一来,文案撰写人员、用户体验文案撰写人员和翻译人员就不必再尝试创建“适合”布局的项目文案。借助子网格,您可以调整布局以适应内容。
详细了解子网格。
排版
2023 年,Web 排版迎来了一些重大更新。一个特别好的渐进增强功能是 text-wrap
属性。此属性可实现排版布局调整,在浏览器中完成,无需额外的脚本。告别不合适的行长,迎接更可预测的排版!
首字母
initial-letter
属性已于年初在 Chrome 110 中推出,是一项小巧而强大的 CSS 功能,可用于设置首字母的放置样式。您可以将字母放置在下沉或上浮状态。该属性接受两个实参:第一个实参用于指定字母在相应段落中的下沉深度,第二个实参用于指定字母在相应段落中的上浮高度。您甚至可以结合使用这两种方法,如以下演示所示。
首字母屏幕截图
首字母演示
::first-letter
伪元素的 initial-letter
值,观察其变化。详细了解 initial-letter。
text-wrap: balance 和 pretty
作为开发者,您不知道标题或段落的最终大小、字号,甚至不知道其语言。浏览器中包含有效且美观地处理文字换行所需的所有变量。由于浏览器知道所有因素(例如字体大小、语言和分配的区域),因此非常适合处理高级别的高质量文本布局。
这时,两种新的文字换行技术就派上用场了,一种称为 balance
,另一种称为 pretty
。balance
值旨在创建和谐的文本块,而 pretty
值旨在防止孤立字词并确保连字符使用得当。这两项任务以前都是手动完成的,现在交给浏览器来完成,并且适用于任何翻译语言,这真是太棒了。
文本换行抓屏
文字环绕实时演示
balance
和 pretty
对标题和段落的影响。尝试将演示翻译成其他语言!详细了解 text-wrap: balance。
颜色
2023 年是 Web 平台的色彩之年。借助可实现动态色彩主题的新颜色空间和函数,您可以尽情创建用户应得的鲜艳、丰富的色彩主题,并让用户能够自定义这些主题!
高清色彩空间(色彩级别 4)
从硬件到软件,从 CSS 到闪烁的灯光;计算机需要做大量工作才能尽可能准确地呈现人眼所能看到的颜色。2023 年,我们推出了新颜色、更多颜色、新颜色空间、颜色函数和新功能。
CSS 和颜色现在可以:
- 检查用户屏幕硬件是否支持广色域 HDR 颜色。
- 检查用户的浏览器是否支持 Oklch 或 Display P3 等颜色语法。
- 以 Oklab、Oklch、HWB、Display P3、Rec.2020、XYZ 等格式指定 HDR 颜色。
- 使用 HDR 颜色创建渐变
- 在替代色彩空间中插值渐变。
- 使用 color-mix()
混合颜色。
- 使用相对颜色语法创建颜色变体。
Color 4 屏幕录制
Color 4 演示
详细了解颜色 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 演示
详细了解如何使用容器查询。
样式容器查询
Browser Support
样式查询已在 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()
演示:不含/含图片的卡片由于 :has()
接受相对选择器列表作为其实参,因此您可以选择的元素远不止父元素。使用各种 CSS 选择器,不仅可以向上遍历 DOM 树,还可以进行横向选择。例如,li:has(+ li:hover)
将选择当前悬停的 <li>
元素之前的 <li>
元素。
:has() 屏幕演示
:has() 演示
:has()
演示:Dock详细了解 CSS :has()
选择器。
更新媒体查询
借助 update
媒体查询,您可以根据设备的刷新率调整界面。该功能可以报告 fast
、slow
或 none
值,这些值与不同设备的功能相关。
您设计的大多数设备可能都具有快速刷新率。这包括桌面设备和大多数移动设备。电子阅读器和低功耗支付系统等设备的刷新率可能较低。了解设备无法处理动画或频繁更新意味着,您可以节省电池用量或避免出现错误的视图更新。
更新“屏幕录制”应用
更新演示
详细了解 @media (update)。
通过脚本编写媒体查询
脚本媒体查询可用于检查 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。详细了解视图过渡。
线性缓动函数
不要被此函数的名称所迷惑。linear()
函数(不要与 linear
关键字混淆)可让您以简单的方式创建复杂的缓动函数,但会损失一些精度。
在 Chrome 113 中发布的 linear()
之前,无法在 CSS 中创建弹跳或弹簧效果。借助 linear()
,我们可以将这些缓动效果简化为一系列点,然后在这些点之间进行线性插值,从而近似实现这些缓动效果。
linear()
函数使用这些点并在它们之间进行线性插值。线性缓动抓屏
线性缓动效果演示
linear()
演示。滚动结束
许多界面都包含滚动互动,有时界面需要同步与当前滚动位置相关的信息,或根据当前状态提取数据。在 scrollend
事件之前,您必须使用不准确的超时方法,该方法可能会在用户的手指仍在屏幕上时触发。借助 scrollend
事件,您可以获得一个完美计时的 scrollend 事件,该事件可以了解用户是否仍在手势操作中。
Scrollend 抓屏
Scrollend 演示
对于浏览器来说,这一点非常重要,因为 JavaScript 无法在滚动期间跟踪手指在屏幕上的位置,根本无法获取相应信息。现在可以删除不准确的滚动结束尝试代码块,并将其替换为浏览器自有高精度事件。
详细了解 scrollend。
滚动条驱动的动画
滚动条驱动的动画是一项令人兴奋的功能,自 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
就可以附加到该变量,从而扩大其范围。这样一来,相应共享父级的所有子级都可以使用该名称的时间轴。
timeline-scope
后,使用滚动条上声明的 scroll-timeline
作为其 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
到 display: none
的动画效果。此规则提供了一种方式,可为元素提供“打开前”样式,以便浏览器在元素于页面上打开之前查找该样式。这对于进入动画以及动画显示弹出式窗口或对话框等元素非常有用。此外,如果您要创建元素并希望为其添加动画效果,此属性也很有用。以以下示例为例,该示例可将 popover
属性(请参阅下一部分)从视口外部平滑地动画显示到视图中并显示到顶层。
@starting-style 抓屏
@starting-style 演示
详细了解 @starting-style 和其他进入动画。
重叠式
您可以将新的 CSS overlay
属性添加到过渡效果中,以使具有顶层样式的元素(例如 popover
和 dialog
)能够平滑地从顶层动画退出。如果您不转换叠加层,元素会立即恢复为被剪裁、转换和遮盖的状态,您将看不到过渡效果。同样,当 overlay
添加到顶层元素时,可使 ::backdrop
平滑地淡出。
叠加式屏幕录制
叠加实时演示
详细了解叠加层和其他退出动画。
组件
2023 年,样式与 HTML 组件的交集取得了重大进展,popover
落地,并且围绕锚点定位和样式化下拉菜单的未来开展了大量工作。借助这些组件,您可以更轻松地构建常见的界面模式,而无需依赖其他库或每次都从头开始构建自己的状态管理系统。
Popover
Popover API 可帮助您构建位于网页其余部分之上的元素。这些内容可能包括菜单、选择和提示。您可以通过以下方式创建一个简单的弹出式窗口:向弹出式窗口元素添加 popover
属性和 id
,并使用 popovertarget="my-popover"
将其 id
属性连接到调用按钮。Popover API 支持:
- 提升到顶层。弹出式窗口将显示在单独的图层上,位于网页的其余部分之上,因此您无需调整 z-index。
- 轻触即关闭功能。点击弹出框区域以外的位置会关闭弹出框并返回焦点。
- 默认焦点管理。打开弹出式窗口后,下一个标签页会停留在弹出式窗口内。
- 无障碍键盘绑定。按
esc
键或双重切换会关闭弹出式信息框并返回焦点。 - 可访问的组件绑定。以语义方式将弹出式信息框元素连接到弹出式信息框触发器。
浮层抓屏
弹出式窗口实时演示
选择框中的水平线
今年在 Chrome 和 Safari 中实现的另一项 HTML 小更改是,能够将水平线元素(<hr>
标记)添加到 <select>
元素中,以帮助直观地分隔内容。以前,将 <hr>
标记放入选择器中根本不会呈现。不过,今年 Safari 和 Chrome 都支持此功能,从而可以更好地分离 <select>
元素中的内容。
选择屏幕截图
选择“实时演示”
详细了解如何在选择器中使用 hr
::user-valid 和 :user-invalid 伪类
:user-valid
和 :user-invalid
今年在所有浏览器中都处于稳定状态,它们的行为与 :valid
和 :invalid
伪类类似,但仅在用户与输入内容进行过显著互动后才匹配表单控件。即使在用户尚未开始与网页互动时,必需且为空的表单控件也会与 :invalid
相匹配。在用户更改输入并使其处于无效状态之前,同一控件不会与 :user-invalid
相匹配。
借助这些新选择器,您不再需要编写有状态的代码来跟踪用户已更改的输入内容。
:user-* 屏幕录制
:user-* 实时演示
详细了解如何使用 user-* 表单验证伪元素。
专属手风琴式折叠视图
Browser Support
Web 上的一种常见界面模式是手风琴组件。如需实现此模式,您可以组合使用多个 <details>
元素,通常以视觉方式将它们分组,以表明它们属于同一组。
Chrome 120 新增了对 <details>
元素上 name
属性的支持。使用此属性时,具有相同 name
值的多个 <details>
元素会形成一个语义组。该组中一次最多只能打开一个元素:当您打开该组中的某个 <details>
元素时,之前打开的元素会自动关闭。这种类型的手风琴称为排他性手风琴。
作为排他性手风琴的一部分的 <details>
元素不一定需要是同级元素。它们可以散布在文档各处。
在过去几年中,尤其是 2023 年,CSS 迎来了复兴。如果您是 CSS 新手,或者只是想复习一下基础知识,不妨查看我们的免费 Learn CSS 课程,以及 web.dev 上提供的其他免费课程。
祝您节日快乐,并希望您能有机会尽快将这些出色的新 CSS 和界面功能融入到您的工作中!
⇾ Chrome 界面开发者关系团队