了解现代 CSS 的一些精彩功能。
目前 CSS 中发生了大量令人兴奋的功能,而当今的浏览器已支持其中许多功能!您可以在下方观看我们在 CDS 2019 大会上的演讲,其中介绍了几项我们认为值得关注的新功能和即将推出的功能。
本博文重点介绍了您目前可以使用的功能,因此请务必观看讲座,更深入地讨论 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
,用于确保视口始终贴靠到最近的贴靠点。
- 将
- 在子级
<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
新媒体查询为我们提供了强大的方式,让我们能够根据用户的设备偏好设置调整应用的用户体验。基本上,浏览器会充当系统级偏好设置的代理,我们可以使用媒体查询的 prefers-*
组在 CSS 中响应这些偏好设置:
以下是我们认为开发者会最感兴趣的新查询:
- 喜欢减少动作
- prefers-color-scheme(首选配色方案)
- prefers-consult
- prefers-reduced-transparency(偏好降低透明度)
- 强制颜色
- 反色
这些查询对于可访问性而言是巨大的优势。例如,在以前,我们无法知道用户是否已将其操作系统设置为高对比度模式。如果您想为 Web 应用提供一种忠实于您的品牌的高对比度模式,就必须让用户从应用内的界面中进行选择。现在,您可以使用 prefers-contrast
在操作系统中检测高对比度设置。
这些媒体查询的一个令人兴奋的后果是,我们可以针对系统级用户偏好设置的多种组合进行设计,以适应各种用户偏好设置和无障碍功能需求。如果用户想要在光线昏暗的环境中使用高对比度的深色模式,您可以这么做!
对 Adam 来说,“更喜欢减少动作”不会实现为“无动作”很重要。用户声称他们喜欢较少的动作,而不是他们不想播放任何动画。他声称减少运动不等于无运动。以下示例展示了当用户更喜欢减少动作时,使用了淡入淡出动画:
逻辑属性
随着越来越多的开发者开始涉足国际化,逻辑属性解决了一个备受关注的问题。margin
和 padding
等许多布局属性都假定语言是从上到下、从左到右。
在设计采用多种语言且具有不同编写模式的网页时,开发者必须针对多个元素分别调整所有属性,这很快就成为了可维护性方面的难题。
通过逻辑属性,您可以在转换和写入模式下保持布局完整性。它们根据内容的语义顺序而不是其空间排列方式动态更新。利用逻辑属性,每个元素都有两个维度:
- 块维度与行中的文本流垂直。(在英语中,
block-size
等同于height
。) - 内嵌维度与每行文字流平行。(在英语中,
inline-size
等同于width
。)
这些维度名称适用于所有逻辑布局属性。因此,例如,在英语中,block-start
等同于 top
,而 inline-end
等同于 right
。
借助逻辑属性,您只需更改页面的 writing-mode
和 direction
属性即可自动更新其他语言的布局,而无需更新单个元素的数十个布局属性。
通过将 <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()
伪类实际上已经有 10 年的历史了,但它的用处仍然没有达到我们的预期。它接受以逗号分隔的选择器列表作为其参数,并匹配该列表中的任何选择器。这种灵活性使其极其方便快捷,并可显著减少您所提交的 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
即将登陆 Flexbox,它提供与网格相同的间距福利:
- 只有一个间距声明,而不是多个。
- 无需为您的项目制定关于哪些子元素应占据间距的惯例,间距由所含元素拥有。
- 相较于旧策略(例如耳袋鼠),其代码更易于理解。
以下视频展示了为两个元素(一个采用网格布局,另一个采用 flex 布局)使用单个 gap
属性的好处:
目前,在 Flex 布局中只有 FireFox 支持 gap
,但不妨观看下面的演示,了解其工作原理:
CSS 胡迪尼
Houdini 是一组适用于浏览器渲染引擎的低阶 API,可让您告知浏览器如何解读自定义 CSS。也就是说,它让您可以访问CSS 对象模型,从而通过 JavaScript扩展CSS。这样做有几个好处:
- 它为您提供了创建自定义 CSS 功能的更多功能。
- 可以更轻松地将渲染问题与应用逻辑分离开来。
- 它比我们目前使用 JavaScript 执行的 CSS polyfill 的性能更高,因为浏览器不再需要解析脚本和执行第二次渲染循环;Houdini 代码将在第一个渲染周期中进行解析。
Houdini 是多个 API 的统称。如果您想详细了解这些人及其当前状态,请参阅 Houdini 准备好了吗?在本次讲座中,我们介绍了 Properties 和 Values API、Paint API 以及 Animation Worklet,因为它们目前受支持。我们可以轻松地针对每个激动人心的 API 专门撰写一篇完整的博文,但现在,请查看我们的演讲,简要了解它们以及一些很棒的演示,了解如何利用这些 API 做些什么。
溢出式菜单
还有一些事情尚未发生,我们想再谈谈,但没时间深入探讨,所以我们快速地对它们进行了一轮讨论。⚡ 如果您还没听说过这些功能,别忘了观看演讲的最后一部分!
size
:用于同时设置高度和宽度的属性aspect-ratio
:该属性用于为本身没有宽高比的元素设置宽高比min()
、max()
和clamp()
:可用于对任何 CSS 属性(而不仅仅是宽度和高度)设置数字约束的函数list-style-type
是现有属性,但很快将支持更多值,包括表情符号和 SVGdisplay: outer inner
:display
属性很快将接受两个参数,让您可以明确指定其外部布局和内部布局,而不是使用inline-flex
等复合关键字。- CSS 区域:可让您填充指定的非矩形区域,内容可以进出
- CSS 模块:JavaScript 将能够请求 CSS 模块,并获取可轻松对其执行操作的丰富对象