Web 平台因创新而蓬勃发展,CSS 和 Web 界面功能是这一激动人心的演变的最前沿。我们正处在网页界面的黄金时代,现在,各种全新 CSS 功能正以前所未有的速度在各大浏览器中推出,这为打造美轮美奂、引人入胜的网络体验打开了无限可能。 这篇博文将深入探讨 CSS 的现状,探讨一些最具颠覆性的新功能,这些功能正在重新定义我们构建 Web 应用的方式,并在 2024 年 Google I/O 大会上进行了直播。
新颖的互动体验
从根本上讲,网络体验就是您与用户之间的一次呼叫和响应,因此,打造高质量的用户互动非常重要。我们一直致力于进行一些非常重大的改进,从而解锁前所未有的功能,让用户可在网页内导航和浏览网页。
滚动条驱动的动画
顾名思义,滚动驱动型动画 API 可让您创建基于滚动的动态动画,而无需依赖滚动观察器或其他大量脚本。
创建滚动条驱动的动画
与基于时间的动画在平台上的运作方式类似,您现在可以使用滚动条的滚动进度来启动、暂停和反向播放动画。因此,当您向前滚动时,您会看到动画进度;如果向后滚动,则会看到动画播放进度相反的情况。这样,您就可以使用在视口内或视口内呈现动画效果的元素制作部分或整页的视觉效果,也称为“滚动式展示”,以获得动态的视觉冲击。
滚动条驱动的动画可用于突出显示重要内容、引导用户浏览故事,或者只是为网页添加动态元素。
滚动条驱动的动画视觉效果
现场演示
@keyframes appear {
from {
opacity: 0;
scale: 0.8;
}
to {
opacity: 1;
scale: 1;
}
}
img {
animation: appear linear;
animation-timeline: view();
animation-range: entry 25% cover 50%;
}
上述代码通过更改图片的不透明度和缩放比例定义了一个在视口中显示的简单动画。动画由滚动位置驱动。如需创建此效果,请先设置 CSS 动画,然后再设置 animation-timeline
。在本例中,view()
函数及其默认值会跟踪相对于滚动端口(在本例中也是视口)的图片。
请务必考虑浏览器支持和用户偏好设置,尤其是针对无障碍功能需求。因此,请使用 @supports
规则检查浏览器是否支持滚动驱动的动画,并将滚动驱动的动画封装在用户偏好设置查询(如 @media (prefers-reduced-motion: no-preference)
)中,以尊重用户的动作偏好设置。完成这些检查后,您就可以知道样式将正常运行,并且动画对用户来说不会出现问题。
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
/* Apply scroll-driven animations here */
}
}
滚动驱动的动画可能意味着全屏滚动讲述体验,但也可能意味着更精细的动画,例如在您滚动 Web 应用时,标题栏会最小化和显示阴影。
滚动条驱动的动画视觉效果
现场演示
@keyframes shrink-name {
from {
font-size: 2em;
}
to {
font-size: 1.5em;
}
}
@keyframes add-shadow {
from {
box-shadow: none;
}
to {
box-shadow: 0 4px 2px -2px gray;
}
}
header {
animation: add-shadow linear both;
}
h2 {
animation: shrink-name linear both;
}
header, h2 {
animation-timeline: scroll();
animation-range: 0 150px;
}
此演示使用几种不同的关键帧动画(标题、文本、导航栏和背景),然后对每个动画应用相应的滚动驱动动画。虽然它们的动画样式不同,但它们都具有相同的动画时间轴、最近的滚动条和相同的动画范围(从页面顶部到 150 像素)。
滚动条驱动的动画的性能优势
无论是您编写的自定义脚本,还是包含其他第三方依赖项,这个内置 API 都能减轻您需要维护的代码负担。它也无需交付各种滚动观察器,这意味着某些显著的性能优势。这是因为,无论是直接在 CSS 中使用新 API 还是使用 JavaScript 钩子,滚动驱动的动画在为可在合成器上添加动画的属性(如变形和不透明度)添加动画效果时,会在主线程以外工作。
Tokopedia 最近使用滚动条驱动的动画,让产品导航栏在您滚动网页时显示。无论是代码管理和性能,使用此 API 都有一些重大优势。
“与使用传统的 JS 滚动事件相比,我们成功地减少了多达 80% 的代码行,并观察到滚动时的平均 CPU 使用率从 50% 降低到 2%。- Andy Wihalim,Tokopedia 高级软件工程师”
滚动效果的未来
我们知道这些影响将继续使网络更具吸引力,我们已经在思考接下来会发生什么。这包括不仅可以使用新的动画时间轴,还可以使用滚动点来触发动画的开始播放(称为滚动触发的动画)。
而且,未来浏览器还会推出更多滚动功能。以下演示组合了这些未来推出的功能。它使用 CSS scroll-start-target
在选择器中设置初始日期和时间,并使用 JavaScript scrollsnapchange
事件更新标头日期,从而轻松地将数据与贴靠事件同步。
您也可以在此基础上,使用 JavaScript scrollsnapchanging
事件实时更新选择器。
这些特定功能目前仅在 Canary 版中使用,但它们解锁了以前在平台中无法构建或非常难以构建的功能,并凸显了基于滚动的互动可能的未来。
如需详细了解如何开始使用滚动条驱动的动画,我们的团队刚刚发布了一个新的视频系列,您可以在 Chrome for Developers YouTube 频道中找到这些视频。在这里,您将学习 Bramus Van Damme 的滚动驱动动画基础知识,包括该功能的运作方式、词汇、各种效果创建方式,以及如何组合效果以打造丰富的体验。这是一个很棒的视频系列,值得一试。
视图过渡
我们刚刚介绍了在网页内添加动画效果的强大新功能,除此之外,还有一项名为“视图转换”的强大新功能,用于在网页浏览之间添加动画效果,从而打造无缝的用户体验。视图过渡为网页带来了全新的流畅性,让您可以在单个页面甚至不同页面的不同视图之间创建无缝过渡。
Airbnb 是一家已在实验将视图过渡集成到其界面中以提供流畅无缝网页导航体验的公司之一。包括商家信息编辑器边栏、直接修改照片和添加酒店设施,所有这一切均可在一个流畅的用户体验流程中完成。
这些全屏显示的效果既美观又顺畅,但您也可以创建微互动,比如这个示例中的列表视图会根据用户互动进行更新。通过视图过渡可以轻松实现这种效果。
在单页应用中快速启用视图过渡的方法非常简单,只需使用 document.startViewTransition
封装交互,并确保每个过渡元素都有 view-transition-name
、内嵌或使用 JavaScript 动态地创建 DOM 节点即可。
直观演示
现场演示
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.startViewTransition(() => {
btn.closest('.card').remove();
});
})
});
/* Styles for the transition animation */
::view-transition-old(.card):only-child {
animation: fade-out ease-out 0.5s;
}
查看过渡类
视图过渡名称可用于将自定义动画应用于视图过渡,但这对于许多元素过渡而言可能会很麻烦。今年,视图过渡的第一次更新简化了此问题,并引入了创建可应用于自定义动画的视图过渡类的功能。
浏览器支持
- 125
- 125
- x
- x
查看过渡类型
视图过渡的另一大改进是支持视图过渡类型。当您在页面视图之间以动画形式呈现动画效果时,如果想要另一种视觉视图过渡效果,视图过渡类型非常有用。
例如,您可能希望首页以不同于博客页面动画返回到首页的方式以动画形式呈现博客页面。或者,您可能希望页面以不同方式来回切换,就像本例中所示,即从左向右或从左到右切换。之前这样做会很麻烦。您可以向 DOM 添加类以应用样式,然后必须移除这些类。View-transition-types 使浏览器可以清理旧转换,而无需在启动新转换之前手动清理,从而为您代劳。
您可以在 document.startViewTransition
函数中设置类型,该函数现在接受一个对象。update
是更新 DOM 的回调函数,types
是包含这些类型的数组。
document.startViewTransition({
update: myUpdate,
types: ['slide', 'forwards']
})
多页面视图转换
网络的普适性之所以如此强大,是因为其拥有的广阔页面空间。许多应用不只是单页,而是包含多个页面的强大挂毯。因此,我们非常高兴地宣布,Chromium 126 将针对多页面应用推出跨文档视图转换支持。
这一新的跨文档功能集包含同源中的网络体验,例如从 web.dev 导航到 web.dev/blog,但不包括跨源导航,例如从 web.dev 导航到 blog.web.dev 或导航到 google.com 等其他网域。
同文档视图过渡的主要区别之一是,您不需要使用 document.startViewTransition()
封装过渡。而是使用 CSS @view-transition
at-rule 来选择启用视图过渡所涉及的两个页面。
@view-transition {
navigation: auto;
}
如需自定义程度更高的效果,您可以使用新的 pageswap
或 pagereveal
事件监听器在 JavaScript 中钩子,它们允许您访问视图转换对象。
借助 pageswap
,您可以在获取旧快照之前,在传出网页上进行一些最后一刻的更改;使用 pagereveal
,您可以在新页面初始化后开始渲染之前对其进行自定义。
window.addEventListener('pageswap', async (e) => {
// ...
});
window.addEventListener('pagereveal', async (e) => {
// ...
});
未来,我们计划在视图转换的基础上扩展,包括:
- 作用域转换:您可以限制向 DOM 子树的转换,使页面的其余部分可继续交互,并支持同时运行多个视图转换。
- 手势驱动的视图转换:使用拖动或滑动手势触发跨文档视图转换,以在网络上获得更接近原生体验的体验。
- CSS 中的导航匹配:直接在 CSS 中自定义跨文档视图过渡,作为在 JavaScript 中使用
pageswap
和pagereveal
事件的替代方案。如需详细了解多页面应用的视图过渡,包括如何以最高性能方式设置预渲染,请观看 Bramus Van Damme 的以下演讲:
支持引擎的界面组件:简化复杂的互动
构建复杂的 Web 应用绝非易事,但 CSS 和 HTML 不断发展完善,使此过程更易于管理。新功能和增强功能简化了界面组件的创建过程,让您可以专注于打造出色的体验。我们通过多个主要标准机构和社区团体(包括 CSS 工作组、开放界面社区小组和 WHATWG(网络超文本应用技术工作组))通力协作完成这项工作。
开发者的一大痛点是提出一项看似简单的请求:为下拉菜单(选择元素)设置样式。从表面上看,这虽然看起来简单明了,但这是一个复杂的问题,涉及平台的许多部分;从布局和渲染,到滚动和互动,再到用户代理样式和 CSS 属性,甚至对 HTML 本身进行更改。
下拉菜单由许多部分组成,包括必须考虑的许多状态,例如:
- 键盘绑定(用于进入/退出互动)
- 点击即可关闭
- 主动管理弹出式窗口(其他弹出式窗口打开时关闭其他弹出式窗口)
- 标签页焦点管理
- 直观呈现所选选项值
- 箭头交互样式
- 状态管理(开放/关闭)
目前很难自行管理所有这些状态,但平台也不容易。为了解决此问题,我们分解了这些部分,并发布了一些基本功能,这些功能可以启用样式下拉菜单,但还有更多功能。
Popover API
首先,我们发布了一个名为 popover
的全局属性,我很高兴地宣布几周前刚刚达到 Baseline 新状态。
弹出式窗口元素通过 display: none
隐藏,直至使用调用器(例如按钮)或 JavaScript 将其打开。如需创建基本弹出式窗口,请在元素上设置弹出式窗口属性,然后使用 popovertarget
将其 ID 关联到按钮。现在,按钮是调用方。
直观演示
现场演示
<button popovertarget="my-popover">Open Popover</button>
<div id="my-popover" popover>
<p>I am a popover with more information.</p>
</div>
启用弹出属性后,浏览器无需任何额外的脚本即可处理许多关键行为,包括:
- 提升到顶层。:在网页其余部分之上单独显示的一层,因此您不必操心
z-index
。 - 轻关闭功能:点击弹出式窗口区域以外的位置,即可关闭弹出式窗口并返回焦点。
- 默认标签页焦点管理:打开弹出式窗口后,下一个标签页就会停止在弹出式窗口内。
- 内置键盘绑定功能:按
esc
键或切换两次将关闭弹出式窗口并返回焦点。 - 默认组件绑定 -:浏览器从语义上将弹出窗口与其触发器相关联。
您甚至可能在没有意识到的情况下使用了此弹出式窗口 API。GitHub 在其首页的“new”菜单和拉取请求审核概览中实现了弹出式窗口。他们使用 popover polyfill(由 Oddbird 构建),并利用 GitHub 自己的 Keith Cirkel 提供的一些重要支持来逐步增强此功能,以便支持旧版浏览器。
“通过迁移到 Popover,我们成功地弃用了数千行代码。Popover 帮我们免去了争夺神奇 Z-index 数字的需要...通过声明性按钮行为建立正确的无障碍树关系,并内置焦点行为,可以大大简化我们的设计系统以正确的方式实现模式。-Keith Cirkel,GitHub 软件工程师”
为进入和退出效果添加动画效果
如果设置了弹出式窗口,您可能希望添加一些互动。我们在过去一年内推出了 4 项新的互动功能,以支持为弹出式窗口添加动画效果。其中包括:
能够在关键帧时间轴上为 display
和 content-visibility
添加动画效果。
将 transition-behavior
属性与 allow-discrete
关键字搭配使用,可实现离散属性(如 display
)的转换。
@starting-style
规则,用于为从 display: none
到顶层的进入效果添加动画效果。
叠加层属性,用于控制动画播放期间的顶层行为。
这些属性适用于您要向顶层添加动画效果的任何元素,无论是弹出式窗口还是对话框。总之,带有背景的对话框应如下所示:
直观演示
现场演示
dialog, ::backdrop{
opacity: 0;
transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}
[open], [open]::backdrop {
opacity: 1;
}
@starting-style {
[open], [open]::backdrop {
opacity: 0;
}
}
首先,设置 @starting-style
,以便浏览器知道要通过哪种样式将此元素添加到 DOM 中。系统会同时对对话框和背景执行此操作。然后,设置对话框和背景的打开状态的样式。对于对话框,这使用 open
属性;对于弹出窗口,这则使用 ::popover-open
伪元素。最后,使用 allow-discrete
关键字为 opacity
、display
和 overlay
添加动画效果,以启用离散属性可以转换的动画模式。
锚点定位
Popover 只是故事的开头。一项激动人心的更新是,Chrome 125 现已提供对锚点定位的支持。
通过使用锚点定位,浏览器只需几行代码即可处理逻辑,以将已定位的元素绑定到一个或多个锚点元素。在以下示例中,简单的提示锚定到位于底部中心的每个按钮。
直观演示
现场演示
在 CSS 中设置锚点位置关系,方法是对锚点元素(本例中为按钮)使用 anchor-name
属性,并对定位的元素(本例中为提示)使用 position-anchor
属性。然后,使用 anchor()
函数应用相对于锚点的绝对定位或固定定位。以下代码可将提示的顶部定位至按钮底部。
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
position-anchor: --my-anchor;
}
或者,直接在锚点函数中使用锚点名称,并跳过 position-anchor
属性。这在锚定到多个元素时很有用。
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
top: anchor(--my-anchor bottom);
}
最后,为 justify
和 align
属性使用新的 anchor-center
关键字,使已定位的元素在其锚点的中心位置。
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
top: anchor(--my-anchor bottom);
justify-self: anchor-center;
}
虽然使用带有弹出窗口的锚点定位非常方便,但使用弹出窗口绝对不是使用锚点定位的必要条件。锚点定位可与任意两个(或更多)元素结合使用,以建立视觉关系。事实上,以下演示的灵感源自 Roman Komarov 的一篇文章,展示了当您将鼠标悬停在列表项上方或按下 Tab 键时,锚定到列表项的下划线样式。
直观演示
现场演示
此示例使用锚点函数,通过 left
、right
和 bottom
的物理属性来设置锚点位置。当您将鼠标悬停在其中一个链接上时,目标锚点会发生变化,浏览器会移动目标以应用定位,同时还会以动画方式呈现颜色以产生简洁的效果。
ul::before {
content: "";
position: absolute;
left: anchor(var(--target) left);
right: anchor(var(--target) right);
bottom: anchor(var(--target) bottom);
...
}
li:nth-child(1) { --anchor: --item-1 }
ul:has(:nth-child(1) a:is(:hover, :focus-visible)) {
--target: --item-1;
--color: red;
}
inset-area
位置
除了您之前可能使用过的默认方向绝对定位之外,还包含一个新布局机制,已作为锚点定位 API 的一部分(称为边衬区)引入。插入区域可让您轻松放置已定位的元素相对于其各自的锚点,它适用于包含 9 个单元格的网格,且锚定元素位于中心位置。例如,inset-area: top
会将已定位的元素置于顶部,inset-area: bottom
则会将已定位的元素置于底部。
使用 inset-area
时,第一个锚点演示的简化版本如下所示:
.anchor {
anchor-name: --my-anchor;
}
.positioned {
position: absolute;
position-anchor: --my-anchor;
inset-area: bottom;
}
您可以将这些位置值与 span 关键字结合使用,以从中心位置开始、向左跨越、跨越全部或全部跨越所有可用列或行。您也可以使用逻辑属性。为了更轻松地查看和采用这种布局机制,请在 Chrome 125 及更高版本中使用此工具:
由于这些元素是锚定的,因此已定位的元素会在其锚点移动时在页面周围动态移动。因此,在本例中,我们拥有容器查询样式的卡片元素,这些元素会根据其固有大小来调整大小(媒体查询无法做到这一点),并且当卡片界面发生变化时,锚定菜单将随新布局而移动。
直观演示
现场演示
使用 position-try-options
的动态锚点位置
将弹出窗口和锚点定位结合使用,可以更轻松地创建菜单和子菜单导航。此外,当您使用锚定元素到达视口边缘时,您也可以让浏览器为您处理位置变化。
您可以通过以下几种方式完成此操作。第一种是创建您自己的定位规则。在这种情况下,子菜单最初位于“店面”按钮的右侧。不过,当菜单右侧没有足够的空间时,您可以创建一个 @position-try
代码块,为其提供自定义标识符 --bottom
。然后,使用 position-try-options
将此 @position-try
代码块连接到锚点。
现在,浏览器将在这些锚定状态之间切换,先尝试切换到正确的位置,然后再切换到底部。这可以通过很好的转场来实现
直观演示
现场演示
#submenu {
position-anchor: --submenu;
top: anchor(top);
left: anchor(right);
margin-left: var(--padding);
position-try-options: --bottom;
transition: top 0.25s, left 0.25s;
width: max-content;
}
@position-try --bottom {
top: anchor(left);
left: anchor(bottom);
margin-left: var(--padding);
}
除了明确的定位逻辑之外,浏览器还提供了一些关键字,供您进行一些基本的互动(例如在块中翻转锚点或内嵌方向)。
position-try-options: flip-block, flip-inline;
为了获得简单的翻转体验,请充分利用这些 flip 关键字值,完全跳过编写 position-try
定义。因此,现在您只需几行 CSS 即可得到一个功能齐全的位置自适应锚点定位元素。
直观演示
现场演示
.tooltip {
inset-area: top;
position-try-options: flip-block;
}
详细了解如何使用锚点定位。
分层界面的未来
我们看到网络共享体验随处可见,这篇博文中展示的功能是一个很好的开端,可以激发创造力,并更好地控制锚定定位元素和分层界面。但这仅仅是个开始。例如,popover
目前只能与作为调用元素的按钮或 JavaScript 配合使用。对于维基百科样式的预览(一种在整个网络平台上看到的模式),它需要能够与之交互,并在链接中触发弹出式窗口,并且如果用户感兴趣,无需点击,例如悬停或标签页焦点。
作为 Popover API 的下一步,我们正致力于开发 interesttarget
来满足这些需求,并让用户更轻松地通过内置的适当的无障碍功能钩子来重建这些体验。这是一个具有挑战性的无障碍功能问题需要解决,其中有许多关于理想行为的开放性问题,但在平台级别解决并标准化此功能应该能够为所有人改善这些体验。
<a interesttarget="my-tooltip">Hover/Focus to show the tooltip</a>
<span popover=hint id="my-toolip">This is the tooltip</span>
此外,得益于两位第三方开发者 Keith Cirkel 和 Luke Warlow 的工作,您还可以在 Canary 中测试另一个面向未来的通用调用程序 (invoketarget
)。invoketarget
支持声明式开发者体验,即 popovertarget
提供弹出式窗口,并针对所有互动元素(包括 <dialog>
、<details>
、<video>
、<input type="file">
等)进行了标准化处理。
<button invoketarget="my-dialog">
Open Dialog
</button>
<dialog id="my-dialog">
Hello world!
</dialog>
我们知道,有些用例未在此 API 的涵盖范围内。例如,对将锚定元素与其锚点相连的箭头进行样式设置(尤其是在锚定元素的位置发生变化时),以及使元素“滑动”并留在视口中,而不是在元素到达其边界框时贴靠到设置的其他位置。因此,在为推出这一强大的 API 感到激动的同时,我们也期待在未来进一步扩展其功能。
为所选样式设置样式
通过结合使用 popover
和 anchor
,该团队在最终实现可自定义的选择下拉菜单方面取得了进展。好消息是,我们已经取得了很大的进展。坏消息是,此 API 目前仍处于实验阶段。不过,我非常高兴能与您分享一些实时演示和最新进展,希望能收到大家的反馈意见。
首先,在如何让用户体验新的可自定义选择体验方面取得了进展。目前,正在为此转换的方法是使用 CSS 中的呈现属性(设置为 appearance: base-select
)。设置外观后,您就可以选择体验一种可自定义的新选择体验。
select {
appearance: base-select;
}
除了 appearance: base-select
之外,还有一些新的 HTML 更新。这些功能包括:将选项封装在 datalist
中以进行自定义,以及在选项中添加任意非互动内容(如图片)。您还可以使用新元素 <selectedoption>
,该元素会在其自身中反映选项的内容,然后您可以根据自己的需求对其进行自定义。这个元素非常方便。
直观演示
现场演示
<select>
<button type=popover>
<selectedoption></selectedoption>
</button>
<datalist>
<option value="" hidden>
<p>Select a country</p>
</option>
<option value="andorra">
<img src="Flag_of_Andorra.svg" />
<p>Andorra</p>
</option>
<option value="bolivia">
<img src="Flag_of_Bolivia.svg" />
<p>Bolivia</p>
</option>
...
</datalist>
</select>
以下代码演示了如何在 Gmail 界面中自定义 <selectedoption>
,其中视觉图标表示为节省空间而选择的回复类型。您可以在 selectedoption
中使用基本显示样式来区分选项样式与预览样式。在本例中,选项中显示的文本可以在 selectedoption
中直观地隐藏起来。
直观演示
现场演示
selectedoption .text {
display: none;
}
为此 API 重复使用 <select>
元素的最大优势之一是向后兼容性。在此国家/地区选择中,您可以看到包含旗帜图片的自定义界面,这些选项有助于用户更轻松地解析内容。由于不受支持的浏览器会忽略它们不能理解的行,例如选项中的自定义按钮、数据列表、 selectedoption 和图片,因此后备选项将与当前的默认选择界面类似。
你可以随心所欲地做选择,带来无限可能。我特别喜欢这个 Airbnb 风格的国家/地区选择器,因为自适应设计有一种巧妙的样式。借助即将推出的风格化选择,您可以执行上述操作以及执行更多操作,这使其成为 Web 平台急需的补充。
直观演示
现场演示
独家手风琴
解决选定样式(以及与之相关的所有组件)并不是 Chrome 团队一直致力于的唯一界面组件。第一个额外组件更新是支持创建专属手风琴,即一次只能打开手风琴中的一项内容
浏览器支持
- 120
- 120
- x
- 17.2
启用此功能的方法是为多个详细信息元素应用相同的名称值,从而创建一个关联的详细信息组,类似于一组单选按钮
<details name="learn-css" open>
<summary>Welcome to Learn CSS!</summary>
</details>
<details name="learn-css">
<summary>Box Model</summary>
<p>...</p>
</details>
<details name="learn-css">
<summary>Selectors</summary>
<p>...</p>
</details>
“:user-valid
”和“:user-invalid
”
另一个界面组件改进是 :user-valid
和 :user-invalid
伪类。:user-valid
和 :user-invalid
伪类最近在所有浏览器中都处于稳定状态,其行为与 :valid
和 :invalid
伪类类似,但仅在用户与输入进行大量互动后才会匹配表单控件。这意味着需要大幅减少所需的代码来确定表单值是否已被交互或已变成“脏”,这对于提供用户反馈非常有用,并且减少了之前执行此操作所需的大量脚本。
演示抓屏
现场演示
input:user-valid,
select:user-valid,
textarea:user-valid {
--state-color: green;
--bg: linear-gradient(...);
}
input:user-invalid,
select:user-invalid,
textarea:user-invalid {
--state-color: red;
--bg: linear-gradient(...);
}
详细了解如何使用用户*表单验证伪元素。
field-sizing: content
最近发布的另一个便捷组件更新是 field-sizing: content
,可应用于输入和文本区域等表单控件。这样可以让输入的大小根据其内容增大(或缩小)。对于文本区域,field-sizing: content
尤其有用,因为不再解析为固定大小,因此可能需要向上滚动,才能在过小的输入框中查看提示之前部分中输入的内容。
浏览器支持
- 123
- 123
- x
- x
演示抓屏
现场演示
textarea, select, input {
field-sizing: content;
}
详细了解字段大小调整。
<select>
:<hr>
在选择操作中启用 <hr>
(即水平规则元素)是另一个小而实用的组件功能。虽然这没有太多的语义用途,但确实可以帮助您很好地区分选定列表中的内容,尤其是您不一定想使用优化组(例如占位值)分组的内容。
选择“屏幕截图”
选择现场演示
<select name="majors" id="major-select">
<option value="">Select a major</option>
<hr>
<optgroup label="School of Fine Arts">
<option value="arthist">
Art History
</option>
<option value="finearts">
Fine Arts
</option>
...
</select>
详细了解如何使用“选择时间”选项
改善生活质量
我们在不断迭代,不仅限于互动和组件。在过去的一年里,还有许多其他的生活质量方面的更新。
先行嵌套
原生 CSS 嵌套于去年在所有浏览器中推出,并且经过改进以支持先行,这意味着不再要求使用元素名称之前的 &
。这使得嵌套更加符合人体工程学,类似于我过去所熟悉的方式。
CSS 嵌套的其中一个特点是,您可以直观地屏蔽组件,并且这些组件中包含状态和修饰符,例如容器查询和媒体查询。以前,出于特定目的,我习惯在文件底部将所有查询分组。现在,您可以通过一种有意义的方式编写这些变量,并将其与其余代码放在一起
.card {
/* card base styles */
h2 {
/* child element style */
}
&.highlight {
/* modifier style */
}
&:hover, &:focus {
/* state styles */
}
@container (width >= 300px) {
/* container query styles */
}
}
为块布局对齐内容
另一个非常好的变化是能够在块布局中使用 align-content
等居中机制。这意味着您现在可以在 div 中执行垂直居中等操作,而无需应用 Flex 布局或网格布局,并且不会出现您可能不希望通过这些布局算法阻止外边距收起的副作用。
浏览器支持
- 123
- 123
- 125
- 17.4
屏幕截图
现场演示
div {
align-content: center;
}
文字环绕:均衡且美观
在布局方面,添加 text-wrap: balance
和 pretty
后,文本布局有了很好的改进。text-wrap: balance
用于更统一的文本块,而 text-wrap: pretty
则侧重于减少文本中最后一行的单例。
演示抓屏
现场演示
h1 {
text-wrap: balance;
}
详细了解文本换行:余额。
国际排版更新
CJK 文本功能的排版布局更新在过去一年中有了很多不错的更新,例如 word-break: auto-phrase
功能,它会在自然短语边界处换行。
浏览器支持
- 119
- 119
- x
- x
以及 text-spacing-trim
,它可以在标点字符之间应用字距调整,以提升中文、日语和韩语排版的可读性,从而提供更赏心悦目的结果。
浏览器支持
- 123
- 123
- x
- x
相对颜色语法
在颜色主题设置方面,相对颜色语法有重大更新。
在此示例中,此处的颜色使用基于 Oklch 的主题。当色相值根据滑块进行调整时,整个主题也会随之变化。这可以通过相对颜色语法来实现。背景会根据色调使用主要颜色,并通过调整亮度、色度和色调通道来调整其值。--i 是值渐变列表中的同级索引,展示了如何将步进与自定义属性和相对颜色语法结合使用来构建主题。
演示抓屏
现场演示
:root {
--hue: 230;
--primary: oklch(70% .2 var(--hue));
}
li {
--_bg: oklch(from var(--primary)
calc(l - (var(--i) * .05))
calc(c - (var(--i) * .01))
calc(h - (var(--i) + 5)));
}
light-dark()
函数
与 light-dark()
函数一起,主题设置变得更加动态和简化。
light-dark()
函数在人体工程学方面进行了改进,简化了颜色主题选项,以便您以更简洁的方式编写主题样式,正如 Adam Argyle 的这张直观示意图所示。之前,您需要两个不同的代码块(默认主题和用户偏好设置查询)来设置主题选项。现在,您可以使用 light-dark()
函数在同一行 CSS 中同时为浅色主题和深色主题编写这些样式选项。
html {
color-scheme: light dark;
}
button {
background-color: light-dark(lightblue, darkblue);
}
如果用户选择了浅色主题,该按钮将具有浅蓝色背景。 如果用户选择了深色主题,该按钮将采用深蓝色背景。
:has()
选择器
我只能介绍一下现代界面,但并未提及过去一年中最具影响力的互操作性亮点之一,那就是 :has()
选择器,它已于去年 12 月跨浏览器推出。此 API 彻底改变了编写逻辑样式的模式。
借助 :has()
选择器,您可以检查子元素是否有特定的子元素,或者这些子元素是否处于特定状态,并且实际上还可以充当父选择器。
事实证明,:has()
对许多公司特别有用,包括 PolicyBazaar。他们使用 :has()
根据内部内容设置区块样式。例如,在比较部分,如果有计划在区块中进行比较,或者区块为空时,样式会调整。
“借助 :has() 选择器,我们得以省去了基于 JavaScript 对用户所选内容的验证,改用 CSS 解决方案,这种解决方案能够与我们顺畅运行,并提供与之前相同的体验。- Aman Soni,PolicyBazaar 技术主管”
容器查询
现在,新的可用且使用量不断增长的 Web 的另一项重要功能是容器查询,它能够查询元素父项的固有尺寸以应用样式:与仅查询视口大小的媒体查询相比,前者要更精细。
Angular 最近在 Angular.dev 上发布了一个精美的新文档网站,该网站使用容器查询根据页面上的可用空间设置标题块的样式。因此,即使布局发生变化,从多列边栏布局变为单列布局,标题块也可以自行调整。
如果没有容器查询,则很难实现此类操作,并且需要调整观察器和元素观察器的大小会降低性能。现在,根据父元素的大小设置元素的样式非常简单。
演示抓屏
现场演示
@property
最后,我们很高兴地看到 @property 进入 Baseline。这是为 CSS 自定义属性(也称为 CSS 变量)提供语义含义的关键功能,还支持大量新的互动功能。@property
还在 CSS 中启用了上下文含义、类型检查、默认值和后备值。打开了范围样式查询等更强大的功能。这是一项前所未有的功能,现在,它为 CSS 语言提供了如此深入的理解。
演示抓屏
现场演示
@property --card-bg {
syntax: "<color>";
inherits: false;
initial-value: #c0bae8;
}
总结
随着各种强大的全新界面功能在各种浏览器上不断推出,您将获得无限可能。新颖的互动体验,以及滚动驱动的动画和视图转换,让 Web 以前所未有的方式变得更加流畅和交互。有了下一级别的界面组件,您可以比以往更轻松地构建功能强大、自定义美观的组件,而不会破坏完整的原生体验。最后,在架构、布局、排版和响应式设计方面改善生活质量不仅解决了一些小问题,还为开发者提供了所需的工具,以便他们构建适用于各种设备、外形规格和用户需求的复杂界面。
通过这些新功能,您应该能够移除第三方脚本,以实现性能密集型功能(例如,通过锚点定位实现滚动叙述和将元素相互共享)、构建流畅的页面转换、最终设置下拉菜单样式,并以原生方式改进代码的整体结构。
现在是成为 Web 开发者的最佳时机。自 CSS3 宣布以来,网站一直没有获得太多能量和激情。过去,我们一直梦寐以求的功能终于成为现实,并成为平台的一部分。正是得益于您的支持,我们才能优先开发并最终让这些功能变为现实。我们正努力让原本繁琐而繁琐的工作变得更轻松,以便您有更多时间打造重要的产品,比如让您的品牌与众不同的核心功能和设计细节。
如需详细了解这些新功能,请访问 developer.chrome.com 和 web.dev,我们的团队会在这里分享网络技术的最新资讯。不妨试用滚动驱动的动画、视图过渡、锚点定位,甚至是样式化选择,并与我们分享您的想法。我们随时乐意倾听,并随时为您提供帮助。