2022年将成为 CSS 最伟大的一年。无论是在功能还是合作浏览器的功能发布方面,合作目标是实现 14 个功能。
概述
本文是在 Google IO 2022上发表的演讲的文字形式。这里不会对每个功能进行深入的讲解,而是对每个功能进行简要概述,提供广度而不是深度。
下面是这些 CSS 功能的概览:
浏览器兼容性
将这么多 CSS 功能设置为合作发布的主要原因是来自 Interop 2022 的努力,下面就来看看 Interop 2022 和 Compat 2021 分别做出了哪些努力。
1. Compat 2021
2021 年的目标是由开发人员通过调查获得的反馈来推动的,旨在稳定当前功能、改进测试套件并提高浏览器在五个功能方面的通过分数:
- sticky 定位
- aspect-ratio 尺寸
- flex 布局
- grid 布局
- transform 定位和动画
测试分数全面提高,显示出更高的稳定性和可靠性。
2. Interop 2022
今年,浏览器们齐心协力,讨论了他们打算开发的功能和优先事项。他们计划为开发者提供以下 web 功能:
- 级联层
@layer
- 颜色空间和方法
- 容器查询
- 表单兼容性
- 滚动
- 子网格
subgrid
- 排版
- 视口单位
- Web 兼容
2022年的新功能
毫不疑问,CSS 2022 的状态受到 Interop 2022 工作的巨大影响。
1. 级联层(@layer)
浏览器支持:
在 @layer
之前,加载样式表的顺序非常重要,因为最后加载的样式会覆盖之前加载的样式。这样开发人员就需要先加载不太重要的样式,然后再加载更重要的样式。
在@layer
之后,入口文件可以预先定义图层及其顺序。 然后,当样式加载、加载完成或已经定义时,它们可以放置在一个层中,允许保留样式覆盖的重要性,但无需精心管理加载顺序。
Chrome DevTools 有助于可视化哪些样式来自哪些图层:
相关资源:
- CSS Cascade 5 specification:www.w3.org/TR/css-casc…
- Cascade layers explainer:css.oddbird.net/layers/expl…
- Cascade layers on MDN:developer.mozilla.org/docs/Web/CS…
- Cascade Layers:developer.chrome.com/blog/cascad…
- Hello, CSS Cascade Layers:www.bram.us/2022/02/13/…
2. 子网格(subgrid)
浏览器支持:
在subgrid
之前,另一个网格中的网格无法与其父单元格或网格线对齐。每个网格布局都是独一无二的。许多设计师在他们的整个设计上放置一个网格,并不断地在其中对齐项目,这在CSS中是做不到的。
在subgrid
之后,网格的子网格可以将其父网格的列或行作为自己的列或行,并将其自身或子网格与它们对齐!
在下面的demo中,body
元素创建了一个经典的三列网格,中间列为main
,左边和右边的列称为fullbleed
。然后,body
中的每个元素, 和 通过设置
grid-template-columns: subgrid
来采用 body
中的命名行。
body { display: grid; grid-template-columns: [fullbleed-start] auto [main-start] min(90%, 60ch) [main-end] auto [fullbleed-end] ; } body > * { display: grid; grid-template-columns: subgrid; }
最后, 或 的子级可以使用 fullbleed
和main
列和行对齐或调整自己的大小。
.main-content { grid-column: main; } .fullbleed { grid-column: fullbleed; }
目前,Firefox Devtools 可以帮助我们查看子网格。 在下图中,父网格和子网格已重叠。 它现在类似于设计师对布局的思考方式。
在 Devtools 的“Elements”面板中,可以看到哪些元素是grid
和subgrid
,这对调试或验证布局是非常有用的。
相关资源:
- Spec:www.w3.org/TR/css-grid…
- MDN:developer.mozilla.org/docs/Web/CS…
- Practical CSS Subgrid Video Tutorials:www.bram.us/2021/11/04/…
3. 容器查询
在 @container
之前,网页的元素只能响应整个视口的大小。 这对于大型布局非常有用,但对于外部容器不是整个视口的小型布局,布局不可能进行相应调整。
在@container
之后,元素可以响应父容器的大小或样式!唯一需要注意的是,容器必须将自己声明为可能的查询目标,这是一个很小的要求,可以带来很大的好处。
/* 新建一个容器 */ .day { container-type: inline-size; container-name: calendar-day; }
以下CSS用于查询 calendar-day
容器大小,然后调整布局和字体大小:
@container calendar-day (max-width: 200px) { .date { display: block; } .date-num { font-size: 2.5rem; display: block; } }
相关资源:
- Spec: https:/www.w3.org/TR/css-cont…
- Explainer:css.oddbird.net/rwd/query/e…
- MDN:developer.mozilla.org/docs/Web/CS…
- The new responsive:web.dev/new-respons…
- Calendar demo by Una:codepen.io/una/pen/Rwo…
- **Awesome container queries: ** github.com/sturobson/A…
- Designcember:web.dev/how-we-buil…
- Container Queries are Actually Coming / Say Hello To CSS Container Queries:www.bram.us/2021/04/14/…
4. accent-color
浏览器支持:
在accent-color
之前,当我们想要一个与品牌颜色匹配的表单时,最终可能需要复杂的库或CSS解决方案,随着时间的推移,这些解决方案会变得难以管理。虽然它们提供了所有选项,并希望包括可访问性,但选择使用内置组件或采用自己的组件会变得单调乏味,无法继续选择。
在accent-color
之后,一行CSS为内置组件带来了主题颜色,除了色调之外,浏览器还会智能地为组件的辅助部分选择适当的对比色,并适应系统配色方案(亮暗)。
/* 为所有颜色着色 */ :root { accent-color: hotpink; } /* 为一个元素着色 */ progress { accent-color: indigo; }
相关资源
- Spec:www.w3.org/TR/css-ui-4…
- MDN:developer.mozilla.org/docs/Web/CS…
- web.dev:web.dev/accent-colo…
- Tint User-Interface Controls with CSS accent-color:www.bram.us/2021/08/23/…
6. Color level 4 and 5
在过去的几十年里,web 一直由 sRGB 主导,但在高清显示器和预先配备 OLED 或 QLED 屏幕的移动设备不断扩大的数字世界中,sRGB 是不够的。 此外,需要适应用户偏好的动态页面,并且颜色管理已成为设计师、设计系统和代码维护人员日益关注的问题。
CSS有许多新的颜色功能和空间(不过不是在2022年):
- 达到显示器高清色彩功能的色彩。
- 与意图相匹配的色彩空间,例如感知一致性。
- 渐变的颜色空间会显著改变插值结果。
- 颜色功能可帮助你混合和对比,并选择在哪个空间进行工作。
在所有这些颜色特性出现之前,设计系统需要预先计算出适当的对比色,并确保调色板具有适当的活力,而预处理器或JavaScript则起到了重要作用。
在完成了所有这些颜色功能之后,浏览器和CSS可以动态、及时地完成所有工作。CSS可以进行编排和计算,而不是向用户发送很大的CSS和JavaScript来启用主题和数据可视化颜色。CSS还可以更好地在使用前检查支持情况,或者优雅地处理回退。
@media (dynamic-range: high) { .neon-pink { --neon-glow: color(display-p3 1 0 1); } } @supports (color: lab(0% 0 0)) { .neon-pink { --neon-glow: lab(150% 160 0); } }
(1)hwb()
浏览器支持:
HWB代表色调、白度和黑度。它表现为一种对人类友好的表达颜色的方式,因为它只是一种色调,加上一定量的白色或黑色以使其变亮或变暗。
:root { --hwb-swatch-1: hwb(200 75% 0%); --hwb-swatch-2: hwb(200 50% 25%); --hwb-swatch-3: hwb(200 25% 50%); --hwb-swatch-4: hwb(200 0% 75%); --hwb-swatch-5: hwb(200 0% 90%); } .swatch:nth-of-type(1) { background: var(--hwb-swatch-1); } .swatch:nth-of-type(2) { background: var(--hwb-swatch-2); } .swatch:nth-of-type(3) { background: var(--hwb-swatch-3); } .swatch:nth-of-type(4) { background: var(--hwb-swatch-4); } .swatch:nth-of-type(5) { background: var(--hwb-swatch-5); } * { box-sizing: border-box; margin: 0; } html { block-size: 100%; } body { min-block-size: 100%; font-family: system-ui, sans-serif; display: grid; }
使用此颜色函数会产生来自 sRGB 颜色空间的颜色,与 HSL 和 RGB 相同。 就 2022 年的新意而言,这并没有给你带来新的色彩,但它可能会让语法和心智模型的粉丝更容易完成一些任务。
相关资源:
- Spec:www.w3.org/TR/css-colo…
- MDN:developer.mozilla.org/docs/Web/CS…
- hwb() – a color notation for humans?:www.stefanjudis.com/blog/hwb-a-…
(2)颜色空间
颜色的表示方式是通过颜色空间完成的。 每个颜色空间都为使用颜色提供了各种功能和权衡。 有些人可能会将所有鲜艳的颜色打包在一起; 有些人可能会先根据它们的亮度排列它们。
2022年, SS 将提供 10 个新的颜色空间,每个都有独特的功能来帮助设计师和开发人员显示、挑选和混合颜色。 以前,sRGB 是处理颜色的唯一选项,但现在 CSS 释放了新的潜力和新的默认颜色空间 LCH。
(3)color-mix()
浏览器支持:
在 color-mix()
之前,开发人员和设计人员需要像 Sass 这样的预处理器在浏览器看到颜色之前混合颜色。大多数颜色混合功能也没有提供指定在哪个颜色空间中进行混合的选项,有时会导致结果混乱。
在 color-mix()
之后,开发人员和设计人员可以在浏览器中混合颜色以及所有其他样式,而无需运行构建过程或包括 JavaScript。 此外,他们可以指定在哪个颜色空间中进行混合,或者使用 LCH 的默认混合颜色空间。
通常,主题颜色被用作基础颜色,并从中创建变体,例如悬停样式的浅色或深色。下面是color-mix()
例子:
.color-mix-example { --brand: #0af; --darker: color-mix(var(--brand) 25%, black); --lighter: color-mix(var(--brand) 25%, white); }
如果你想在不同的颜色空间中混合这些颜色,例如 srgb,请更改它:
.color-mix-example { --brand: #0af; --darker: color-mix(in srgb, var(--brand) 25%, black); --lighter: color-mix(in srgb, var(--brand) 25%, white); }
在 2022 年享受在你的样式表中混合各种颜色空间的颜色!
相关资源:
- Spec:www.w3.org/TR/css-colo…
- MDN:developer.mozilla.org/docs/Web/CS…
- Theming demo:codepen.io/argyleink/p…
- Another theming demo:codepen.io/argyleink/p…
- Create a color theme with CSS Relative Color Syntax, CSS color-mix(), and CSS color-contrast():www.bram.us/2021/04/28/…
(4)color-contrast()
浏览器支持:
在 color-contrast()
之前,样式表作者需要提前了解可访问的颜色。 通常,调色板会在颜色样本上显示黑色或白色文本,以向颜色系统的用户指示需要哪种文本颜色才能与该样本进行适当对比。
在 color-contrast()
之后,样式表作者可以将任务完全转移到浏览器。 你不仅可以使用浏览器自动选择黑色或白色,还可以为其提供设计系统适用的颜色列表,并让其选择第一个通过所需对比度的颜色。
这是 HWB 调色板集 demo 的截图,其中文本颜色由浏览器根据样本颜色自动选择:
语法的基本内容如下所示,其中灰色被传递给函数,浏览器确定黑色或白色是否具有最大对比度:
css
color: color-contrast(gray);
该函数还可以使用颜色列表进行自定义,它将从中选择对比度最高的颜色:
color: color-contrast(gray vs indigo, rebeccapurple, hotpink);
最后,如果最好不要从列表中选择对比度最高的颜色,可以提供目标对比度,并选择第一种通过该对比度的颜色:
color: color-contrast( var(--bg-blue-1) vs var(--text-lightest), var(--text-light), var(--text-subdued) to AA /* 4.5 could also be passed */ );
这个函数不仅可以用于文本颜色,但这将是它的主要用途。 想一想,一旦选择适当的对比色内置到 CSS 语言本身中,那么交付可访问且易读的界面将变得多么容易。
相关资源:
(5)相对颜色语法
浏览器支持:
在使用相对颜色语法之前,为了计算颜色并进行调整,需要将颜色通道单独放置到自定义属性中。这一限制还使HSL成为处理颜色的主要颜色函数,因为色调、饱和度或亮度都可以通过 calc()
直接调整。
在相对颜色语法之后,任何空间中的任何颜色都可以解构、修改并作为颜色返回,所有这些都可以在CSS的一行中完成。在任何所需的颜色空间中,都无法对HSL操作进行更多限制,并且需要创建更少的自定义属性来简化操作。
在以下语法示例中,提供了一个基本十六进制,并相对于它创建了两种新颜色。 第一种颜色 --absolute-change
在 LCH 中从基色创建新颜色,然后继续将基色的亮度替换为 75%,保持色度 (c) 和色相 (h)。 第二种颜色 --relative-change
在 LCH 中从基色创建新颜色,但这一次将色度 (c) 降低了 20%。
.relative-color-syntax { --color: #0af; --absolute-change: lch(from var(--color) 75% c h); --relative-change: lch(from var(--color) l calc(c-20%) h); }
它类似于混合颜色,但它更像是改变而不是混合。 你可以从另一种颜色创建一种颜色,访问所用颜色函数命名的三个通道值,并有机会调整这些通道。 总而言之,这是一种非常酷且强大的颜色语法。
在下面的例子中,使用了相对颜色语法来创建基色的更亮和更暗的变体,并使用 color-contrast()
来确保标签具有适当的对比度:
此函数也可用于调色板生成。 这是一个例子,其中整个调色板是根据提供的基色生成的。 这套 CSS 支持所有不同的调色板,每个调色板只是提供不同的基色。
:root { --_color-base: #339af0; --color-0: lch(from var(--_color-base) 98% 10 h); --color-1: lch(from var(--_color-base) 93% 20 h); --color-2: lch(from var(--_color-base) 85% 40 h); --color-3: lch(from var(--_color-base) 75% 46 h); --color-4: lch(from var(--_color-base) 66% 51 h); --color-5: lch(from var(--_color-base) 61% 52 h); --color-6: lch(from var(--_color-base) 55% 57 h); --color-7: lch(from var(--_color-base) 49% 58 h); --color-8: lch(from var(--_color-base) 43% 55 h); --color-9: lch(from var(--_color-base) 39% 52 h); --color-10: lch(from var(--_color-base) 32% 48 h); --color-11: lch(from var(--_color-base) 25% 45 h); --color-12: lch(from var(--_color-base) 17% 40 h); --color-13: lch(from var(--_color-base) 10% 30 h); --color-14: lch(from var(--_color-base) 5% 20 h); --color-15: lch(from var(--_color-base) 1% 5 h); }
相关资源:
- Spec:www.w3.org/TR/css-colo…
- Palettes:codepen.io/web-dot-dev…
- Variants:codepen.io/web-dot-dev…
(6)渐变颜色空间
在渐变颜色空间之前,sRGB 是使用的默认颜色空间。 sRGB 通常是可靠的,但确实有一些弱点,例如灰色死区。
在渐变颜色空间之后,告诉浏览器使用哪个颜色空间进行颜色插值。 这使开发人员和设计人员能够选择他们喜欢的渐变。 默认色彩空间也更改为 LCH 而不是 sRGB。
语法添加在渐变方向之后,使用新的in
语法,并且是可选的:
background-image: linear-gradient( to right in hsl, black, white ); background-image: linear-gradient( to right in lch, black, white );
这是从黑色到白色的基本且必不可少的渐变。 查看每个颜色空间中的结果范围。 有些更早达到深黑色,有些更晚达到白色。
在下一个示例中,黑色转换为蓝色,因为它是渐变的已知问题空间。 大多数颜色空间在颜色插值期间会逐渐变为紫色。或者,当颜色在其颜色空间内从 A 点移动到 B 点时。由于渐变将从 A 点到 B 点采用直线,因此色彩空间的形状变化极大地改变了路径沿途的停止点。
okLCH 和 okLAB 是专门的色彩空间,可以解释各种变化,比如这个变成紫色的,这使得它们对于渐变特别准确。
相关资源:
- Spec:drafts.csswg.org/css-images-…
- Codepen comparing gradients:codepen.io/argyleink/p…
- Observable notebook:observablehq.com/@argyleink/…
7. inert
浏览器支持:
在 inert
之前,将用户的注意力引导到需要立即关注的页面或应用程序区域是一种很好的做法。 这种引导式焦点策略被称为焦点捕获,因为开发人员会将焦点置于交互空间中,监听焦点更改事件,如果焦点离开交互空间,则强制返回。使用键盘或屏幕阅读器的用户会被引导回到互动空间,以确保在继续完成之前的任务。
在inert
之后,不需要设置陷阱,因为你可以冻结或保护页面或应用程序的整个部分。当文档的这些部分处于惰性状态时,单击和焦点更改尝试根本不可用。你也可以把它想象成守卫而不是陷阱,惰性分子不想让你待在某个地方,而是让其他地方不可用。
请注意,在调用 alert()
之前,页面是如何通过鼠标和键盘访问的。显示警报对话框弹出窗口后,页面的其余部分将被冻结或不活动。用户的注意力放在警报对话框中,无处可去。一旦用户交互并完成警报功能请求,页面将再次交互。inert
使开发人员能够轻松实现同样的引导焦点体验。
下面示例来展示它是如何工作的:
<body> <div class="modal"> <h2>Modal Title</h2> <p>...<p> <button>Save</button> <button>Discard</button> </div> <main inert> <!-- cannot be keyboard focused or clicked --> </main> </body>
对话框是一个很好的例子,但inert
也有助于诸如滑出式侧边菜单用户体验之类的事情。 当用户滑出侧边菜单时,让鼠标或键盘与后面的页面交互是不合适的;相反,当显示侧边菜单时,使页面处于inert
状态,现在用户必须关闭或在该侧边菜单中导航,并且永远不会发现自己在打开菜单的页面中迷失在其他地方。
相关资源:
- Spec:html.spec.whatwg.org/multipage/i…
- MDN:developer.mozilla.org/docs/Web/AP…
- Introducing inert:developer.chrome.com/blog/inert/
Google IO 2022——CSS 状态(下)https://developer.aliyun.com/article/1410894