新一代网页样式设置

了解现代 CSS 中的一些令人兴奋的功能。

CSS 目前正在发生许多令人兴奋的事情,而且其中许多功能已经在当今的浏览器中受支持!您可以在下方观看我们在 2019 年 CDS 大会上的演讲,其中介绍了我们认为值得关注的几项新功能和即将推出的功能。

这篇博文重点介绍您目前可以使用的功能,因此请务必观看讲座,以便更深入地讨论 Houdini 等即将推出的功能。 您还可以在 CSS@CDS 页面上找到我们所讨论的所有功能的演示。

目录

滚动贴靠

滚动贴靠功能可让您定义在用户垂直和/或水平滚动内容时的贴靠点。它提供内置滚动惯性和减速功能,并且支持触摸。

以下示例代码在 <section> 元素中设置水平滚动,并将吸附点与 <picture> 子元素的左侧对齐:

section {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
}

section > picture {
  scroll-snap-align: start;
}

具体方法如下:

  • 在父 <section> 元素上,
    • overflow-x 设置为 auto 以允许水平滚动。
    • overscroll-behavior-x 设为 contain,以防止在用户到达 <section> 元素滚动区域的边界时,任何父元素滚动。(这对于贴靠而言并非绝对必要,但通常是一个好主意。)
    • scroll-snap-type 设置为 x(用于水平贴靠)和 mandatory(设置为 mandatory),以确保视口始终贴靠最近的贴靠点。
  • 在子 <picture> 元素上,scroll-snap-align 设为开始位置,这样可以设置每张照片左侧的贴靠点(假设 direction 设置为 ltr)。

下面是实时演示:

您还可以查看垂直滚动卡顿矩阵滚动卡顿的演示。

:focus-within

:focus-within 解决了一个长期存在的无障碍问题:在许多情况下,聚焦子元素应会影响父元素的呈现,以便辅助技术用户能够访问界面。

例如,如果您的下拉菜单包含多个项目,则当任何项目获得焦点时,该菜单应保持可见状态。否则,键盘用户看到的菜单会消失。

:focus-within 告知浏览器当焦点位于指定元素的任何子元素上时应用样式。回到菜单示例,通过在菜单元素上设置 :focus-within,您可以确保菜单项获得焦点时菜单元素保持可见:

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

一张插图,显示了“聚焦”和“聚焦内”之间的行为差异。

请尝试在下方的演示中按 Tab 键浏览可聚焦的元素。您会发现,当您聚焦于菜单项时,菜单会保持可见状态:

媒体查询级别 5

借助新的媒体查询,我们可以通过强大的途径根据用户的设备偏好调整应用的用户体验。从本质上讲,浏览器充当系统级偏好设置的代理,我们可以在 CSS 中使用 prefers-* 组媒体查询来响应这些偏好设置:

显示媒体查询如何解读系统级用户偏好的图表。

以下是我们认为开发者最感兴趣的新查询:

这些查询对于无障碍功能来说是巨大的胜利。例如,以前我们无法知道用户是否已将操作系统设为高对比度模式。如果您想为 Web 应用提供高对比度模式,同时保持品牌风格,则必须让用户从应用内的界面中选择该模式。现在,您可以使用 prefers-contrast 从操作系统中检测高对比度设置。

这些媒体查询的一个令人兴奋的含义是,我们可以针对系统级用户偏好的多种组合进行设计,以满足各种用户偏好和无障碍需求。如果用户希望在光线昏暗的环境中使用高对比度深色模式,您可以为其提供此模式!

Adam 认为,“首选减少动画”不应实现为“无动画”,这一点非常重要。用户表示他们更喜欢减少动作,而不是不希望任何动画。他断言减少动画效果并不等同于无动画效果。以下示例在用户偏好减少动作时使用了交叉淡出动画:

逻辑属性

随着越来越多的开发者开始进军国际化,逻辑属性解决了这一日益明显的问题。许多布局属性(例如 marginpadding)都假定语言的阅读顺序为从上到下、从左到右。

显示传统 CSS 布局属性的示意图。

在为采用不同书写模式的多种语言设计网页时,开发者必须在多个元素中单独调整所有这些属性,这很快就会成为维护噩梦。

借助逻辑属性,您可以在各种翻译和编写模式下保持布局完整性。它们根据内容的语义排序(而不是其空间排列)动态更新。使用逻辑属性时,每个元素都有两个维度:

  • 尺寸与一行文本的流向呈垂直。(在英语中,block-sizeheight 相同。)
  • “内嵌”维度与一行中的文本流平行(在英语中,inline-sizewidth 相同。)

这些尺寸名称适用于所有逻辑布局属性。例如,在英语中,block-starttop 相同,inline-endright 相同。

显示新的 CSS 逻辑布局属性的示意图。

借助逻辑属性,您只需更改网页的 writing-modedirection 属性,即可自动更新其他语言的布局,而无需更新各个元素上的数十个布局属性。

您可以通过将 <body> 元素上的 writing-mode 属性设置为不同的值,在以下演示中了解逻辑属性的运作方式:

position: sticky

具有 position: sticky 的元素会一直保持在块流中,直到开始超出屏幕边界为止。此时,该元素会停止与页面的其余部分一起滚动,并固定在元素的 top 值指定的位置。为该元素分配的空间会保留在流中,当用户滚动回上方时,该元素会返回到该空间。

借助粘性定位,您可以创建之前需要 JavaScript 才能实现的许多实用效果。为了展示一些可能性,我们创建了几个演示。每个演示都使用大致相同的 CSS,只需稍微调整 HTML 标记即可创建每种效果。

粘性堆叠

在此演示中,所有固定元素都共用一个容器。也就是说,当用户向下滚动时,每个固定元素都会滑过上一个固定元素。固定元素共用相同的固定位置。

粘性幻灯片

在这里,固定元素是同类元素。(即,他们的父母是兄弟姐妹。)当粘性元素到达其容器的下边界时,它会随容器一起向上移动,给人一种低层粘性元素会推高高粘性元素的印象。也就是说,它们似乎在争夺卡顿位置。

Sticky Desperado

与粘性幻灯片一样,此演示中的粘性元素也是同级元素。但是,它们被放置在设置为双列网格布局的容器中。

backdrop-filter

借助 backdrop-filter 属性,您可以将图形效果应用于元素的后面区域,而不是应用于元素本身。这样一来,许多之前只能通过复杂的 CSS 和 JavaScript 技巧实现的酷炫效果,现在只需一行 CSS 代码即可实现。

例如,此演示使用 backdrop-filter 实现了操作系统风格的模糊处理:

我们已经撰写了一篇关于 backdrop-filter 的优质博文,您可以参阅该博文了解详情。

:is()

虽然 :is() 伪类已经有十多年的历史,但我们认为其使用率仍然不高。它接受逗号分隔的选择器列表作为其参数,并匹配该列表中的所有选择器。这种灵活性使其极为便利,并且可以显著减少您配送的 CSS 数量。

一个简单的示例:

button.focus,
button:focus {
  
}

article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
  
}

/* selects the same elements as the code above */
button:is(.focus, :focus) {
  
}

article > :is(h1,h2,h3,h4,h5,h6) {
  
}

gap

CSS 网格布局使用 gap(之前为 grid-gap)已有一段时间。通过指定容器元素的内部间距(而不是子元素周围的间距),gap 可以解决许多常见的布局问题。例如,使用 gap 时,您无需担心子元素的外边距会导致包含元素边缘周围出现不必要的空白:

插图:展示 gap 属性如何避免在容器元素边缘周围出现意外间距。

更好的消息是:gap 即将支持 Flexbox,并带来与网格相同的间距优势:

  • 只有一个间距声明,而不是多个。
  • 您无需为项目建立有关哪些子元素应拥有间距的惯例,而是由包含元素拥有间距。
  • 脑部切除的猫头鹰等旧版策略相比,该代码更易于理解。

以下视频展示了对两个元素(一个采用网格布局,另一个采用 Flex 布局)使用单个 gap 属性的好处:

目前,只有 Firefox 支持在 Flex 布局中使用 gap,但您可以试用此演示来了解其运作方式:

CSS Houdini

Houdini 是一组面向浏览器渲染引擎的低级 API,可让您告知浏览器如何解读自定义 CSS。换句话说,它可让您访问 CSS 对象模型,从而通过 JavaScript extend CSS。这样做有几个好处:

  • 它为您提供了更强大的功能来创建自定义 CSS 功能。
  • 更容易将渲染问题与应用逻辑分离。
  • 与我们目前使用 JavaScript 进行的 CSS polyfill 相比,这种方法的性能更高,因为浏览器不再需要解析脚本并执行第二次渲染周期;Houdini 代码会在第一次渲染周期中解析。

插图:Houdini 与传统 JavaScript polyfill 相比的工作方式。

Houdini 是多个 API 的总称。如需详细了解这些功能及其当前状态,请参阅 Houdini 是否已准备就绪?在我们的演讲中,我们介绍了属性和值 API、绘制 API 以及动画 Worklet,因为它们目前是受支持的最强工具。我们可以轻松为这些令人兴奋的 API 各自撰写一篇完整的文章,但现在,请先观看我们的演讲,了解这些 API 的概览以及一些很酷的演示,以便初步了解您可以使用这些 API 做些什么。

溢出

我们还想讨论其他一些内容,但没时间深入讲解,所以我们进行了一次快速讨论。⚡ 如果您还没有听说过其中一些功能,请务必观看讲座的最后一部分

  • size:一个属性,可让您同时设置高度和宽度
  • aspect-ratio:用于为本质上不具有宽高比的元素设置宽高比的属性
  • min()max()clamp():可让您对任何 CSS 属性(而不仅仅是宽度和高度)设置数字约束条件的函数
  • list-style-type 是一个现有属性,但很快将支持更多值,包括表情符号和 SVG
  • display: outer innerdisplay 属性很快将接受两个参数,让您可以明确指定其外部和内部布局,而不是使用 inline-flex 等复合关键字。
  • CSS 区域:可让您填充指定的非矩形区域,内容可在其中流入和流出
  • CSS 模块:JavaScript 将能够请求 CSS 模块,并传回易于对操作的丰富对象