简单的了解下 css 在 2022 年有哪些新特性

简单的了解下 css 在 2022 年有哪些新特性_第1张图片

2022年将成为 CSS 最伟大的一年。无论是在功能还是合作浏览器的功能发布方面,合作目标是实现 14 个功能。

概述

本文是在 Google IO 2022上发表的演讲的文字形式。这里不会对每个功能进行深入的讲解,而是对每个功能进行简要概述,提供广度而不是深度。

下面是这些 CSS 功能的概览:

简单的了解下 css 在 2022 年有哪些新特性_第2张图片

浏览器兼容性

将这么多 CSS 功能设置为合作发布的主要原因是来自 Interop 2022 的努力,下面就来看看 Interop 2022 和 Compat 2021 分别做出了哪些努力。

1. Compat 2021

2021 年的目标是由开发人员通过调查获得的反馈来推动的,旨在稳定当前功能、改进测试套件并提高浏览器在五个功能方面的通过分数:

  1. sticky 定位

  2. aspect-ratio 尺寸

  3. flex 布局

  4. grid 布局

  5. transform 定位和动画

测试分数全面提高,显示出更高的稳定性和可靠性。

2. Interop 2022

今年,浏览器们齐心协力,讨论了他们打算开发的功能和优先事项。他们计划为开发者提供以下 web 功能:

  1. 级联层@layer

  2. 颜色空间和方法

  3. 容器查询

  4. 表单兼容性

  5. 滚动

  6. 子网格subgrid

  7. 排版

  8. 视口单位

  9. Web 兼容

2022年的新功能

毫不疑问,CSS 2022 的状态受到 Interop 2022 工作的巨大影响。

1. 级联层(@layer)

浏览器支持:

简单的了解下 css 在 2022 年有哪些新特性_第3张图片

在 @layer 之前,加载样式表的顺序非常重要,因为最后加载的样式会覆盖之前加载的样式。这样开发人员就需要先加载不太重要的样式,然后再加载更重要的样式。

@layer之后,入口文件可以预先定义图层及其顺序。然后,当样式加载、加载完成或已经定义时,它们可以放置在一个层中,允许保留样式覆盖的重要性,但无需精心管理加载顺序。

简单的了解下 css 在 2022 年有哪些新特性_第4张图片

上图展示了级联层如何允许更自由、更开放地编写和加载过程。同时仍然根据需要维护层叠。

Chrome DevTools 有助于可视化哪些样式来自哪些图层:

简单的了解下 css 在 2022 年有哪些新特性_第5张图片

相关资源:

  • CSS Cascade 5 specification: https://www.w3.org/TR/css-cascade-5/#layering

  • Cascade layers explainer: https://css.oddbird.net/layers/explainer/

  • Cascade layers on MDN: https://developer.mozilla.org/docs/Web/CSS/@layer

  • Cascade Layers: https://developer.chrome.com/blog/cascade-layers/

  • Hello, CSS Cascade Layers: https://www.bram.us/2022/02/13/hello-css-cascade-layers/

2. 子网格(subgrid)

浏览器支持:

简单的了解下 css 在 2022 年有哪些新特性_第6张图片

subgrid之前,另一个网格中的网格无法与其父单元格或网格线对齐。每个网格布局都是独一无二的。许多设计师在他们的整个设计上放置一个网格,并不断地在其中对齐项目,这在CSS中是做不到的。

subgrid之后,网格的子网格可以将其父网格的列或行作为自己的列或行,并将其自身或子网格与它们对齐!

在下面的demo中,body元素创建了一个经典的三列网格,中间列为main,左边和右边的列称为fullbleed。然后,body 中的每个元素, 

          

对话框是一个很好的例子,但inert也有助于诸如滑出式侧边菜单用户体验之类的事情。当用户滑出侧边菜单时,让鼠标或键盘与后面的页面交互是不合适的;相反,当显示侧边菜单时,使页面处于inert状态,现在用户必须关闭或在该侧边菜单中导航,并且永远不会发现自己在打开菜单的页面中迷失在其他地方。

相关资源:

  • Spec: https://html.spec.whatwg.org/multipage/interaction.html#inert

  • MDN: https://developer.mozilla.org/docs/Web/API/HTMLElement/inert

  • Introducing inert: https://developer.chrome.com/blog/inert/

8. COLRv1 字体

在 COLRv1 字体之前,Web 有 OT-SVG 字体,这也是一种开放格式,用于渐变字体、内置颜色和效果。不过,它们可能会变得非常大,虽然它们允许编辑文本,但定制的空间不大。

在 COLRv1 字体之后,Web 具有更小的占用空间、矢量可缩放、可重新定位、渐变功能和混合模式驱动的字体,它们接受参数来自定义每个用例的字体或匹配主题。

简单的了解下 css 在 2022 年有哪些新特性_第25张图片

下面是 Chrome Developer 博客文章中有关表情符号的示例。也许你已经注意到,如果你放大表情符号的字体大小,它就不会保持清晰。这是一个图像,而不是矢量艺术。使用 COLRv1 字体,表情符号既矢量又漂亮:

简单的了解下 css 在 2022 年有哪些新特性_第26张图片

图标字体可以用这种格式做一些惊人的事情,提供自定义的双色调调色板等等。加载 COLRv1 字体就像任何其他字体文件一样:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

自定义 COLRv1 字体使用 @font-palette-values 完成的,这是一个特殊的 CSS 规则,用于将一组自定义选项分组和命名为一个包以供以后参考。指定自定义名称就像自定义属性一样,以 -- 开头:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

使用 --colorized 作为自定义的别名,最后一步是将调色板应用于使用颜色字体系列的元素:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);

@font-palette-values --colorized {
  font-family: "Bungee Spice";
  base-palette: 0;
  override-colors: 0 hotpink, 1 cyan, 2 white;
}

.spicy {
  font-family: "Bungee Spice";
  font-palette: --colorized;
}
简单的了解下 css 在 2022 年有哪些新特性_第27张图片

随着越来越多的可变字体和彩色字体的出现,网页排版正朝着丰富的定制和创造性表达的方向发展。

相关资源:

  • Github: https://github.com/googlefonts/colr-gradients-spec

  • Chrome Developers: https://developer.chrome.com/blog/colrv1-fonts/

  • BlinkOn developer explainer video: https://www.youtube.com/watch?v=BmqYm5Wwz8M

9. 视口单位

简单的了解下 css 在 2022 年有哪些新特性_第28张图片

在新的视口变体之前,web提供了物理单位来帮助适应视口。有高度、宽度、最小尺寸 (vmin) 和最大边 (vmax)。这些对很多事情都有效,但移动浏览器带来了复杂性。

在移动设备上,加载页面时,会显示带有 url 的状态栏,此栏会占用部分视口空间。在几秒钟和一些交互之后,状态栏可能会滑开,以便为用户提供更大的视口体验。但是当该条滑出时,视口高度发生了变化,任何 vh 单位都会随着目标大小的变化而移动和调整大小。在后来的几年里,vh 单位特别需要决定要使用两种视口尺寸中的哪一种,因为这会在移动设备上造成不和谐的视觉布局问题。已确定 vh 将始终代表最大的视口。

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}

在新的视口变体之后,可以使用小型、大型和动态视口单位,并在物理视口单元的基础上添加逻辑等效单位。这个想法是让开发人员和设计人员能够选择他们想要在给定场景中使用的单位。当状态栏消失时,也许可以稍微改变一下不协调的布局,这样就可以不用担心使用dvh(动态视口高度)。

简单的了解下 css 在 2022 年有哪些新特性_第29张图片

以下是新视口变体提供的所有新视口单位选项的完整列表:

/* 高度视口单位 */
.new-height-viewport-units {
  height: 100vh;
  height: 100dvh;
  height: 100svh;
  height: 100lvh;
  block-size: 100vb;
  block-size: 100dvb;
  block-size: 100svb;
  block-size: 100lvb;
}

/* 宽度视口单位 */
.new-width-viewport-units {
  width: 100vw;
  width: 100dvw;
  width: 100svw;
  width: 100lvw;
  inline-size: 100vi;
  inline-size: 100dvi;
  inline-size: 100svi;
  inline-size: 100lvi;
}

/* 最小视口单位 */
.new-min-viewport-units {
  --size: 100vmin;
  --size: 100dvmin;
  --size: 100svmin;
  --size: 100lvmin;
}

/* 最大视口单位 */
.new-max-viewport-units {
  --size: 100vmax;
  --size: 100dvmax;
  --size: 100svmax;
  --size: 100lvmax;
}

希望这些将为开发人员和设计人员提供实现其视口响应式设计所需的灵活性。

相关资源:

  • Spec: https://drafts.csswg.org/css-values-4/#viewport-relative-lengths

  • The Large, Small, and Dynamic Viewports: https://www.bram.us/2021/07/08/the-large-small-and-dynamic-viewports/

10. :has()

浏览器支持:

简单的了解下 css 在 2022 年有哪些新特性_第30张图片

在 :has() 之前,选择器的主体总是在最后。例如,这个选择器的主体是一个列表项:ul > li。伪选择器可以改变选择器,但它们不会改变主体:ul > li:hover 或 ul > li:not(.selected)

在 :has() 之后,元素树中较高的主体可以保留为主体,同时提供有关子项的查询:ul:has(> li)。很容易理解 :has() 是如何获得“父选择器”的通用名称的,因为在这种情况下,选择器的主体现在是父级。

这是一个基本语法示例,其中 .parent 类仍然是主体,但仅在子元素具有 .child 类时才被选中:

.parent:has(.child) {...}

这是一个示例,其中 

 元素是主体,但选择器仅在其中一个子元素具有 :focus-visible 时才匹配:

section:has(*:focus-visible) {...}

:has()选择器开始成为一个神奇的实用工具,因为实际用例变得更加明显。例如,当前无法在包装图像时选择标签,因此很难确定锚定标记在该用例中如何更改其样式。可以使用 :has() 实现:

a:has(> img) {...}

这些都是 :has() 看起来像父选择器的例子。如果图片有 

,请考虑 
 元素内图像的用例和调整图像的样式。在以下示例中,选择带有 figcaptions 的图像,然后选择该上下文中的图像。使用:has() 不会改变主体,因为我们的目标是图像而不是数字:

figure:has(figcaption) img {...}

使用 @supports 及其 selector() 函数使检查支持变得简单,该函数在使用之前测试浏览器是否支持该语法:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}

相关资源:

  • Spec: https://www.w3.org/TR/selectors-4/#relational

  • MDN: https://developer.mozilla.org/docs/Web/CSS/:has

  • The CSS :has() selector is way more than a "parent selector": https://www.bram.us/2021/12/21/the-css-has-selector-is-way-more-than-a-parent-selector/

2022年及以后的功能

在所有这些令人惊叹的功能在 2022 年登陆之后,仍有许多事情将难以完成。下面来介绍一些剩余的问题以及正在积极开发的解决方案。这些解决方案是实验性的,即使它们可能在浏览器的标志后面被指定或可用。

1. 松散类型的自定义属性

浏览器支持:

简单的了解下 css 在 2022 年有哪些新特性_第31张图片

CSS 自定义属性是惊人的。它们允许将各种事物存储在命名变量中,然后可以对其进行扩展、计算、共享等。事实上,它们是如此灵活,如果有一些不太灵活的东西会更好。

考虑一个场景,其中长方体阴影使用自定义属性作为其值:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);

这一切都会正常运行,直到任何一个属性更改为 CSS 不接受的值,例如 --x: red。如果任何一个嵌套变量丢失或设置为无效的值类型,则整个阴影会中断。

这就是@property 的用武之地:--x 可以成为一个类型化的自定义属性,不再松散和灵活,但在某些定义的边界下是安全的:

@property --x {
  syntax: '';
  initial-value: 0px;
  inherits: false;
}

现在,当 box-shadow 中的var(--x) 使用 --x: red 时,red 将被忽略,因为它不是 。这意味着阴影会继续正常工作,即使为其自定义属性之一提供了无效值。它没有失败,而是恢复到其初始值 0px

除了类型安全之外,它还为动画打开了许多大门。CSS 语法的灵活性使得某些动画变得不可能,比如渐变。@property 在这里会很有用,因为类型化的 CSS 属性可以告知浏览器开发人员在其他过于复杂的插值中的意图。它本质上限制了可能性的范围,以至于浏览器可以为以前无法实现的样式的各个方面设置动画。

考虑下面的例子,其中使用径向渐变来制作覆盖的一部分,从而创建聚光灯聚焦效果。按下alt/opt键时,JavaScript设置鼠标xy,然后将焦点大小更改为较小的值,例如25%,在鼠标位置创建聚光灯焦点圆:

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y), 
    transparent 0%, 
    transparent var(--focal-size), 
    black 0%
  );
}

不过,渐变无法设置动画。它们对于浏览器来说太灵活和太复杂了,无法理解你希望它们如何制作动画。但是,使用@property,可以单独设置一个属性并为其设置动画,浏览器可以轻松理解其意图。

使用这种聚焦效果的电子游戏始终会为圆设置动画,从一个大圆到一个针孔圆。下面是如何在演示中使用@property,以便浏览器为渐变遮罩设置动画:

@property --focal-size {
  syntax: '';
  initial-value: 100%;
  inherits: false;
}

.focus-effect {
  --focal-size: 100%;
  --mouse-x: center;
  --mouse-y: center;

  mask-image: radial-gradient(
    circle at var(--mouse-x) var(--mouse-y), 
    transparent 0%, 
    transparent var(--focal-size), 
    black 0%
  );

  transition: --focal-size .3s ease;
}

浏览器现在能够为渐变大小设置动画,因为我们已将修改的表面积减少到只有一个属性并设置值,以便浏览器可以智能地插入长度。

相关资源:

  • Spec: https://www.w3.org/TR/css-properties-values-api-1/#at-property-rule

  • MDN: https://developer.mozilla.org/docs/Web/CSS/@property

  • web.dev: https://web.dev/at-property/

  • Zoom demo: https://codepen.io/argyleink/pen/rNwWwor

  • CSS Tricks: https://css-tricks.com/exploring-property-and-its-animating-powers/

2. 媒体查询范围

在媒体查询范围之前,CSS 媒体查询使用 min-width 和 max-width 来表达条件。它可能看起来像这样:

@media (min-width: 320px) {
  …
}

在媒体查询范围之后,相同的媒体查询可能如下所示:

@media (320px >= width) {
  …
}

使用 min-width 和 max-width 的 CSS 媒体查询可能如下所示:

@media (min-width: 320px) and (max-width: 1280px) {
  …
}

在媒体查询范围之后,相同的媒体查询可能如下所示:

@media (320px <= width <= 1280px) {
  …
}

后者看起来会比前者更清晰。由于规范的增加,开发人员将能够选择他们喜欢的,甚至可以互换使用它们。

相关资源:

  • Spec: https://www.w3.org/TR/mediaqueries-5/#mq-range-context

  • MDN: https://developer.mozilla.org/docs/Web/CSS/Media_Queries/Using_media_queries#syntax_improvements_in_level_4

  • PostCSS plugin: https://github.com/postcss/postcss-media-minmax

3. 自定义媒体查询

@custom-media 之前,媒体查询必须一次又一次地重复,或者依赖预处理器在构建期间基于静态变量生成正确的输出。

@custom-media 之后,CSS允许对媒体查询进行定义别名和引用,就像自定义属性一样。

命名非常重要:它可以使目的与语法保持一致,使事物更易于共享,更易于在团队中使用。以下是一些自定义媒体查询:

@custom-media --OSdark  (prefers-color-scheme: dark);
@custom-media --OSlight (prefers-color-scheme: light);

@custom-media --pointer (hover) and (pointer: coarse);
@custom-media --mouse   (hover) and (pointer: fine);

@custom-media --xxs-and-above (width >= 240px);
@custom-media --xxs-and-below (width <= 240px);

现在它们已定义,我可以像这样使用其中一个:

@media (--OSdark) {
  :root {
    …
  }
}

相关资源

  • Spec: https://www.w3.org/TR/mediaqueries-5/#custom-mq

  • PostCSS plugin: https://github.com/postcss/postcss-custom-media

4. 嵌套选择器

在 @nest之前,样式表中有很多重复。当选择器很长且每个选择器都针对微小的差异时,它变得特别笨拙。所以,我们会经常使用预处理器的嵌套功能。

在 @nest 之后,重复就消失了。几乎所有支持预处理器的嵌套功能都将内置在 CSS 中。

article {
  color: darkgray;
}

article > a {
  color: var(--link-color);
}

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}

除了避免重复的代码,嵌套最重要的是样式上下文保留在一个样式块中。读者无需从一个选择器及其样式跳到另一个带有样式的选择器(示例 1),而是可以留在文章的上下文中并查看文章在其中拥有链接。

考虑一个子组件,它希望在不同的父级上下文中调整自己,而不是父组件拥有样式并更改子组件:

/* parent owns this, adjusting children */
section:focus-within > article {
  border: 1px solid hotpink;
}

/* with @nest becomes */

/* article owns this, adjusting itself when inside a section:focus-within */
article {
  @nest section:focus-within > & {
     border: 1px solid hotpink;
  }
}

@nest 总体上有助于更健康的风格组织、集中化和所有权。组件可以分组并拥有自己的样式,而不是让它们散布在其他样式块中。在这些示例中,它可能看起来很小,但为了方便和易读性,它可以产生非常大的影响。

相关资源:

  • Spec: https://www.w3.org/TR/css-nesting-1/

  • PostCSS plugin: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting

  • The future of CSS: Nesting Selectors: https://www.bram.us/2019/03/17/the-future-of-css-nesting-selectors/

5. 样式范围

在 @scope 之前,存在许多策略,因为 CSS 中的样式在默认情况下是级联、继承和全局作用域的。CSS 的这些特性在很多方面都非常方便,但对于复杂的站点和应用程序,可能有许多不同样式的组件,级联的全局空间和性质会使样式感觉像是在泄漏。

在 @scope 之后,样式不仅可以限定在一个上下文中,就像一个类一样,它们还可以明确样式的结束位置,并且不会继续级联或继承。

在以下示例中,BEM 命名约定范围可以转换为实际意图。BEM 选择器试图将 header 元素的颜色范围限定为具有命名约定的 .card 容器。这要求header上有这个类名,从而完成目标。使用 @scope,无需命名约定即可在不标记header元素的情况下完成相同的目标:

.card__header {
  color: var(--text);
}

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}

下面是另一个例子,不特定于组件,更多的是关于 CSS 的全局范围性质。深色和浅色主题必须在样式表中共存,其中顺序在确定获胜风格时很重要。通常这意味着深色主题样式出现在浅色主题之后;这将浅色设置为默认样式,将深色设置为可选样式。避免与 @scope的排序和范围之争:

@scope (.light-theme) {
  a { color: purple; }
}

@scope (.dark-theme) {
  a { color: plum; }
}

@scope 还允许建立样式范围的结束位置。这不能通过任何命名约定或预处理器来完成;它很特别,只有浏览器内置的 CSS 才能做到。在以下示例中,当 .media-block 的子项是 .content 的兄弟或父项时,将专门应用 img 和 .content 样式:

@scope (.media-block) to (.content) {
  img {
    border-radius: 50%;
  }

  .content {
    padding: 1em;
  }
}

相关资源:

  • Spec: https://www.w3.org/TR/css-scoping-1/

  • Explainer: https://css.oddbird.net/scope/explainer/

6. 瀑布流布局

在使用Grid实现CSS瀑布流布局之前,JavaScript是实现瀑布流布局的最佳方式,因为任何带有列或flexbox的CSS方法都会不准确地表示内容顺序。使用grid构建CSS后,将不需要JavaScript库,内容顺序也将正确。

简单的了解下 css 在 2022 年有哪些新特性_第32张图片

上图使用以下 CSS 实现:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}

相关资源:

  • Spec: https://drafts.csswg.org/css-grid-3/#masonry-layout-algorithm

  • MDN: https://developer.mozilla.org/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout

  • Smashing Magazine: https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

7. CSS保存数据

在 prefers-reduced-data媒体查询之前,JavaScript 和服务器可以根据用户的操作系统或浏览器的“data saver”选项更改其行为,但 CSS 不能。

在 prefers-reduced-data 媒体查询之后,CSS 可以加入用户体验增强,并在保存数据方面发挥作用。

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}

在这个媒体滚动组件中使用了前面的CSS,节省了很多资源。根据访问视口的大小,可以在页面加载上节省更多资源。当用户与媒体滚动条交互时,继续保存。这些图像上都有load="lazy"属性,再加上CSS完全隐藏元素,这意味着永远不会对图像发出网络请求。

简单的了解下 css 在 2022 年有哪些新特性_第33张图片

对于我的测试,在一个中等大小的视口上,最初加载了 40 个请求和 700kb 的资源。当用户滚动媒体选择时,会加载更多请求和资源。使用 CSS prefers-reduced-data媒体查询,加载了 10 个请求和 172kb 的资源。这节省了半兆字节,用户甚至没有滚动任何媒体,此时没有其他请求。

简单的了解下 css 在 2022 年有哪些新特性_第34张图片

这种减少数据体验的优势不仅仅是节省资源。可以看到更多标题,并且没有分散注意力的封面图片来吸引注意力。许多用户在数据保护模式下浏览,因为他们按每兆字节的数据付费——很高兴看到 CSS 能够在这里提供帮助。

相关资源:

  • Spec: https://www.w3.org/TR/mediaqueries-5/#prefers-reduced-data

  • MDN: https://developer.mozilla.org/docs/Web/CSS/@media/prefers-reduced-data

  • GUI Challenges: https://gui-challenges.web.app/media-scroller/dist/

  • Smashing Magazine: https://www.smashingmagazine.com/2021/12/core-web-vitals-case-study-smashing-magazine/#savedata-and-prefers-reduced-data

8. 滚动快照

在这些滚动快照提案之前,需要编写自己的 JavaScript 来管理轮播、滑块或图库,并且可能会很复杂,需要所有的观察者和状态管理。此外,如果不小心,自然滚动速度可能会被脚本标准化,使用户交互感觉有点不自然并且可能很笨拙。

(1)snapChanging()

浏览器一发布快照子项,就会触发此事件。这允许用户界面反映缺少快照子项和滚动条的不确定快照状态,因为它现在正在使用,并将在新的地方落地。

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
(2)snapChanged()

一旦浏览器捕捉到一个新的子对象,滚动条停止,就会触发此事件。这使得任何依赖于快照子对象的UI都可以更新并反映连接。

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
(3)scroll-start

滚动并不总是从一开始就开始。考虑一下可滑动组件,其中向左或向右滑动会触发不同的事件,或者页面加载时的搜索栏最初是隐藏的,直到滚动到顶部。这个CSS属性允许开发者指定一个滚动条应该从一个特定的点开始。

:root { --nav-height: 100px }

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
(4):snap-target

这个 CSS 选择器将匹配滚动捕捉容器中当前被浏览器捕捉的元素。

.card {
  --shadow-distance: 5px;
  box-shadow: 0 var(--shadow-distance) 5px hsl(0 0% 0% / 25%);
  transition: box-shadow 350ms ease;
}

.card:snapped {
  --shadow-distance: 30px;
}

在这些滚动快照提案之后,制作滑块、轮播或图库要容易得多,因为浏览器现在为任务提供了便利,消除了观察者和滚动编排代码,有利于使用内置 API。

这些 CSS 和 JS 功能还处于早期阶段,但请留意可以帮助尽快采用和测试它们的 polyfill。

相关资源:

  • Draft spec: https://drafts.csswg.org/css-scroll-snap-2/

  • Explainers: https://github.com/argyleink/ScrollSnapExplainers/blob/main/css-snap-target/readme.md

  • Snap demos: https://snap-gallery.netlify.app/

9. CSS状态

在 toggle()之前,只有浏览器内置的状态才能用于样式和交互。例如,复选框输入具有 :checked,这是一种内部管理的浏览器状态,用于 CSS 能够用于视觉更改元素的输入。

在 toggle() 之后,可以在任何元素上创建自定义状态,以便 CSS 更改和用于样式。它允许循环、定向切换等。

在以下示例中,实现了与完整列表项删除线相同的效果,但没有任何复选框元素:


  
  • 1 banana   
  • 1 cup blueberries     ...
  • 以及相关的 CSS toggle() 样式:

    li {
      toggle-root: check self;
    }
    
    li:toggle(check) {
      text-decoration: line-through;
    }

    如果你熟悉状态机,可能会注意到 toggle() 有多少交叉。这个特性将让开发人员将更多的状态构建到 CSS 中,希望能以更清晰、更语义化的方式来编排交互和状态。

    相关资源:

    • Draft: https://tabatkins.github.io/css-toggle/

    • The Future of CSS: CSS Toggles: https://www.bram.us/2022/04/20/the-future-of-css-css-toggles/

    10. 自定义选择元素

    在  之前,CSS 无法使用丰富的 HTML 自定义  元素或更改选项列表的显示方式。这导致开发人员加载外部库,这些库重新创建了