新增了 14 個(gè) CSS 新功能,太實(shí)用了【Google IO 2022】

2022年將成為 CSS 最偉大的一年。無(wú)論是在功能還是合作瀏覽器的功能發(fā)布方面,合作目標(biāo)是實(shí)現(xiàn) 14 個(gè)功能。

概述
本文是在 Google IO 2022上發(fā)表的演講的文字形式。這里不會(huì)對(duì)每個(gè)功能進(jìn)行深入的講解,而是對(duì)每個(gè)功能進(jìn)行簡(jiǎn)要概述,提供廣度而不是深度。

下面是這些 CSS 功能的概覽:


瀏覽器兼容性
將這么多 CSS 功能設(shè)置為合作發(fā)布的主要原因是來(lái)自 Interop 2022 的努力,下面就來(lái)看看 Interop 2022 和 Compat 2021 分別做出了哪些努力。

1. Compat 2021
2021 年的目標(biāo)是由開(kāi)發(fā)人員通過(guò)調(diào)查獲得的反饋來(lái)推動(dòng)的,旨在穩(wěn)定當(dāng)前功能、改進(jìn)測(cè)試套件并提高瀏覽器在五個(gè)功能方面的通過(guò)分?jǐn)?shù):

sticky 定位
aspect-ratio 尺寸
flex 布局
grid 布局
transform 定位和動(dòng)畫(huà)
測(cè)試分?jǐn)?shù)全面提高,顯示出更高的穩(wěn)定性和可靠性。

2. Interop 2022
今年,瀏覽器們齊心協(xié)力,討論了他們打算開(kāi)發(fā)的功能和優(yōu)先事項(xiàng)。他們計(jì)劃為開(kāi)發(fā)者提供以下 web 功能:

級(jí)聯(lián)層@layer
顏色空間和方法
容器查詢
<dialog>
表單兼容性
滾動(dòng)
子網(wǎng)格subgrid
排版
視口單位
Web 兼容
2022年的新功能
毫不疑問(wèn),CSS 2022 的狀態(tài)受到 Interop 2022 工作的巨大影響。

1. 級(jí)聯(lián)層(@layer)
瀏覽器支持:


在 @layer 之前,加載樣式表的順序非常重要,因?yàn)樽詈蠹虞d的樣式會(huì)覆蓋之前加載的樣式。這樣開(kāi)發(fā)人員就需要先加載不太重要的樣式,然后再加載更重要的樣式。

在@layer之后,入口文件可以預(yù)先定義圖層及其順序。然后,當(dāng)樣式加載、加載完成或已經(jīng)定義時(shí),它們可以放置在一個(gè)層中,允許保留樣式覆蓋的重要性,但無(wú)需精心管理加載順序。


上圖展示了級(jí)聯(lián)層如何允許更自由、更開(kāi)放地編寫(xiě)和加載過(guò)程。同時(shí)仍然根據(jù)需要維護(hù)層疊。

Chrome DevTools 有助于可視化哪些樣式來(lái)自哪些圖層:


相關(guān)資源:

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. 子網(wǎng)格(subgrid)
瀏覽器支持:


在subgrid之前,另一個(gè)網(wǎng)格中的網(wǎng)格無(wú)法與其父單元格或網(wǎng)格線對(duì)齊。每個(gè)網(wǎng)格布局都是獨(dú)一無(wú)二的。許多設(shè)計(jì)師在他們的整個(gè)設(shè)計(jì)上放置一個(gè)網(wǎng)格,并不斷地在其中對(duì)齊項(xiàng)目,這在CSS中是做不到的。

在subgrid之后,網(wǎng)格的子網(wǎng)格可以將其父網(wǎng)格的列或行作為自己的列或行,并將其自身或子網(wǎng)格與它們對(duì)齊!

在下面的demo中,body元素創(chuàng)建了一個(gè)經(jīng)典的三列網(wǎng)格,中間列為main,左邊和右邊的列稱為fullbleed。然后,body 中的每個(gè)元素, <nav> 和 <main> 通過(guò)設(shè)置 grid-template-columns: subgrid 來(lái)采用 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;
}
最后,<nav> 或 <main> 的子級(jí)可以使用 fullbleed 和main列和行對(duì)齊或調(diào)整自己的大小。

.main-content {
  grid-column: main;
}

.fullbleed {
  grid-column: fullbleed;
}
完整示例:https://codepen.io/web-dot-dev/pen/JjMQzVV

目前,F(xiàn)irefox Devtools 可以幫助我們查看子網(wǎng)格。在下圖中,父網(wǎng)格和子網(wǎng)格已重疊。它現(xiàn)在類似于設(shè)計(jì)師對(duì)布局的思考方式。


在 Devtools 的“Elements”面板中,可以看到哪些元素是grid和subgrid,這對(duì)調(diào)試或驗(yàn)證布局是非常有用的。


相關(guān)資源:

Spec: https://www.w3.org/TR/css-grid-2/#subgrids
MDN: https://developer.mozilla.org/docs/Web/CSS/CSS_Grid_Layout/Subgrid
Practical CSS Subgrid Video Tutorials: https://www.bram.us/2021/11/04/practical-css-subgrid-video-tutorials/
3. 容器查詢
在 @container 之前,網(wǎng)頁(yè)的元素只能響應(yīng)整個(gè)視口的大小。這對(duì)于大型布局非常有用,但對(duì)于外部容器不是整個(gè)視口的小型布局,布局不可能進(jìn)行相應(yīng)調(diào)整。

在@container之后,元素可以響應(yīng)父容器的大小或樣式!唯一需要注意的是,容器必須將自己聲明為可能的查詢目標(biāo),這是一個(gè)很小的要求,可以帶來(lái)很大的好處。

/* 新建一個(gè)容器 */
.day {
  container-type: inline-size;
  container-name: calendar-day;
}
這些樣式使下圖中的 Mon、Tues、Wed、Thurs 和 Fri 列能夠被事件元素查詢。


以下CSS用于查詢 calendar-day 容器大小,然后調(diào)整布局和字體大?。?br>
@container calendar-day (max-width: 200px) {
  .date {
    display: block;
  }

  .date-num {
    font-size: 2.5rem;
    display: block;
  }
}
下面是另一個(gè)示例:一個(gè)book組件根據(jù)其拖動(dòng)到的列中的可用空間進(jìn)行調(diào)整:


相關(guān)資源:

Spec: https:/www.w3.org/TR/css-contain-3/#container-queries
Explainer: https://css.oddbird.net/rwd/query/explainer/
MDN: https://developer.mozilla.org/docs/Web/CSS/CSS_Container_Queries
The new responsive: https://web.dev/new-responsive/#responsive-to-the-container
Calendar demo by Una: https://codepen.io/una/pen/RwodQZw
Awesome container queries:  https://github.com/sturobson/Awesome-Container-Queries
Designcember: https://web.dev/how-we-built-designcember/
Container Queries are Actually Coming / Say Hello To CSS Container Queries: https://www.bram.us/2021/04/14/container-queries-are-actually-coming-say-hello-to-css-container-queries/
4. accent-color
瀏覽器支持:


在accent-color之前,當(dāng)我們想要一個(gè)與品牌顏色匹配的表單時(shí),最終可能需要復(fù)雜的庫(kù)或CSS解決方案,隨著時(shí)間的推移,這些解決方案會(huì)變得難以管理。雖然它們提供了所有選項(xiàng),并希望包括可訪問(wèn)性,但選擇使用內(nèi)置組件或采用自己的組件會(huì)變得單調(diào)乏味,無(wú)法繼續(xù)選擇。

在accent-color之后,一行CSS為內(nèi)置組件帶來(lái)了主題顏色,除了色調(diào)之外,瀏覽器還會(huì)智能地為組件的輔助部分選擇適當(dāng)?shù)膶?duì)比色,并適應(yīng)系統(tǒng)配色方案(亮暗)。

/* 為所有顏色著色 */
:root {
  accent-color: hotpink;
}

/* 為一個(gè)元素著色 */
progress {
  accent-color: indigo;
}

相關(guān)資源

Spec: https://www.w3.org/TR/css-ui-4/#widget-accent
MDN: https://developer.mozilla.org/docs/Web/CSS/accent-color
web.dev: https://web.dev/accent-color/
Tint User-Interface Controls with CSS accent-color:https://www.bram.us/2021/08/23/tint-user-interface-controls-with-css-accent-color/
6. Color level 4 and 5
在過(guò)去的幾十年里,web 一直由 sRGB 主導(dǎo),但在高清顯示器和預(yù)先配備 OLED 或 QLED 屏幕的移動(dòng)設(shè)備不斷擴(kuò)大的數(shù)字世界中,sRGB 是不夠的。此外,需要適應(yīng)用戶偏好的動(dòng)態(tài)頁(yè)面,并且顏色管理已成為設(shè)計(jì)師、設(shè)計(jì)系統(tǒng)和代碼維護(hù)人員日益關(guān)注的問(wèn)題。

CSS有許多新的顏色功能和空間(不過(guò)不是在2022年):

達(dá)到顯示器高清色彩功能的色彩。
與意圖相匹配的色彩空間,例如感知一致性。
漸變的顏色空間會(huì)顯著改變插值結(jié)果。
顏色功能可幫助你混合和對(duì)比,并選擇在哪個(gè)空間進(jìn)行工作。
在所有這些顏色特性出現(xiàn)之前,設(shè)計(jì)系統(tǒng)需要預(yù)先計(jì)算出適當(dāng)?shù)膶?duì)比色,并確保調(diào)色板具有適當(dāng)?shù)幕盍?,而預(yù)處理器或JavaScript則起到了重要作用。

在完成了所有這些顏色功能之后,瀏覽器和CSS可以動(dòng)態(tài)、及時(shí)地完成所有工作。CSS可以進(jìn)行編排和計(jì)算,而不是向用戶發(fā)送很大的CSS和JavaScript來(lái)啟用主題和數(shù)據(jù)可視化顏色。CSS還可以更好地在使用前檢查支持情況,或者優(yōu)雅地處理回退。

@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代表色調(diào)、白度和黑度。它表現(xiàn)為一種對(duì)人類友好的表達(dá)顏色的方式,因?yàn)樗皇且环N色調(diào),加上一定量的白色或黑色以使其變亮或變暗。

: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;
}
效果如下:


使用此顏色函數(shù)會(huì)產(chǎn)生來(lái)自 sRGB 顏色空間的顏色,與 HSL 和 RGB 相同。就 2022 年的新意而言,這并沒(méi)有給你帶來(lái)新的色彩,但它可能會(huì)讓語(yǔ)法和心智模型的粉絲更容易完成一些任務(wù)。

相關(guān)資源:

Spec: https://www.w3.org/TR/css-color-4/#the-hwb-notation
MDN: https://developer.mozilla.org/docs/Web/CSS/color_value/hwb()
hwb() – a color notation for humans?: https://www.stefanjudis.com/blog/hwb-a-color-notation-for-humans/
(2)顏色空間
顏色的表示方式是通過(guò)顏色空間完成的。每個(gè)顏色空間都為使用顏色提供了各種功能和權(quán)衡。有些人可能會(huì)將所有鮮艷的顏色打包在一起;有些人可能會(huì)先根據(jù)它們的亮度排列它們。

2022年, SS 將提供 10 個(gè)新的顏色空間,每個(gè)都有獨(dú)特的功能來(lái)幫助設(shè)計(jì)師和開(kāi)發(fā)人員顯示、挑選和混合顏色。以前,sRGB 是處理顏色的唯一選項(xiàng),但現(xiàn)在 CSS 釋放了新的潛力和新的默認(rèn)顏色空間 LCH。

(3)color-mix()
瀏覽器支持:


在 color-mix()之前,開(kāi)發(fā)人員和設(shè)計(jì)人員需要像 Sass 這樣的預(yù)處理器在瀏覽器看到顏色之前混合顏色。大多數(shù)顏色混合功能也沒(méi)有提供指定在哪個(gè)顏色空間中進(jìn)行混合的選項(xiàng),有時(shí)會(huì)導(dǎo)致結(jié)果混亂。

在 color-mix() 之后,開(kāi)發(fā)人員和設(shè)計(jì)人員可以在瀏覽器中混合顏色以及所有其他樣式,而無(wú)需運(yùn)行構(gòu)建過(guò)程或包括 JavaScript。此外,他們可以指定在哪個(gè)顏色空間中進(jìn)行混合,或者使用 LCH 的默認(rèn)混合顏色空間。

通常,主題顏色被用作基礎(chǔ)顏色,并從中創(chuàng)建變體,例如懸停樣式的淺色或深色。下面是color-mix() 例子:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(var(--brand) 25%, black);
  --lighter: color-mix(var(--brand) 25%, white);
}
如果你想在不同的顏色空間中混合這些顏色,例如 srgb,請(qǐng)更改它:

.color-mix-example {
  --brand: #0af;

  --darker: color-mix(in srgb, var(--brand) 25%, black);
  --lighter: color-mix(in srgb, var(--brand) 25%, white);
}
在 2022 年享受在你的樣式表中混合各種顏色空間的顏色!

相關(guān)資源:

Spec: https://www.w3.org/TR/css-color-5/#color-mix
MDN: https://developer.mozilla.org/docs/Web/CSS/color_value/color-mix()
Theming demo: https://codepen.io/argyleink/pen/WNoWadG
Another theming demo: https://codepen.io/argyleink/pen/YzZQYMq
Create a color theme with CSS Relative Color Syntax, CSS color-mix(), and CSS color-contrast(): https://www.bram.us/2021/04/28/create-a-color-theme-with-css-relative-color-syntax-css-color-mix-and-css-color-contrast/
(4)color-contrast()
瀏覽器支持:


在 color-contrast() 之前,樣式表作者需要提前了解可訪問(wèn)的顏色。通常,調(diào)色板會(huì)在顏色樣本上顯示黑色或白色文本,以向顏色系統(tǒng)的用戶指示需要哪種文本顏色才能與該樣本進(jìn)行適當(dāng)對(duì)比。


在 color-contrast() 之后,樣式表作者可以將任務(wù)完全轉(zhuǎn)移到瀏覽器。你不僅可以使用瀏覽器自動(dòng)選擇黑色或白色,還可以為其提供設(shè)計(jì)系統(tǒng)適用的顏色列表,并讓其選擇第一個(gè)通過(guò)所需對(duì)比度的顏色。

這是 HWB 調(diào)色板集 demo 的截圖,其中文本顏色由瀏覽器根據(jù)樣本顏色自動(dòng)選擇:


語(yǔ)法的基本內(nèi)容如下所示,其中灰色被傳遞給函數(shù),瀏覽器確定黑色或白色是否具有最大對(duì)比度:

color: color-contrast(gray);
該函數(shù)還可以使用顏色列表進(jìn)行自定義,它將從中選擇對(duì)比度最高的顏色:

color: color-contrast(gray vs indigo, rebeccapurple, hotpink);
最后,如果最好不要從列表中選擇對(duì)比度最高的顏色,可以提供目標(biāo)對(duì)比度,并選擇第一種通過(guò)該對(duì)比度的顏色:

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 */
);
這個(gè)函數(shù)不僅可以用于文本顏色,但這將是它的主要用途。想一想,一旦選擇適當(dāng)?shù)膶?duì)比色內(nèi)置到 CSS 語(yǔ)言本身中,那么交付可訪問(wèn)且易讀的界面將變得多么容易。

相關(guān)資源:

Spec: https://www.w3.org/TR/css-color-5/#colorcontrast
MDN: https://developer.mozilla.org/docs/Web/CSS/color_value/color-contrast()
Demo: https://codepen.io/web-dot-dev/pen/qBpzwZW
(5)相對(duì)顏色語(yǔ)法
瀏覽器支持:


在使用相對(duì)顏色語(yǔ)法之前,為了計(jì)算顏色并進(jìn)行調(diào)整,需要將顏色通道單獨(dú)放置到自定義屬性中。這一限制還使HSL成為處理顏色的主要顏色函數(shù),因?yàn)樯{(diào)、飽和度或亮度都可以通過(guò) calc() 直接調(diào)整。






在相對(duì)顏色語(yǔ)法之后,任何空間中的任何顏色都可以解構(gòu)、修改并作為顏色返回,所有這些都可以在CSS的一行中完成。在任何所需的顏色空間中,都無(wú)法對(duì)HSL操作進(jìn)行更多限制,并且需要?jiǎng)?chuàng)建更少的自定義屬性來(lái)簡(jiǎn)化操作。

在以下語(yǔ)法示例中,提供了一個(gè)基本十六進(jìn)制,并相對(duì)于它創(chuàng)建了兩種新顏色。第一種顏色 --absolute-change 在 LCH 中從基色創(chuàng)建新顏色,然后繼續(xù)將基色的亮度替換為 75%,保持色度 (c) 和色相 (h)。第二種顏色 --relative-change 在 LCH 中從基色創(chuàng)建新顏色,但這一次將色度 (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);
}
它類似于混合顏色,但它更像是改變而不是混合。你可以從另一種顏色創(chuàng)建一種顏色,訪問(wèn)所用顏色函數(shù)命名的三個(gè)通道值,并有機(jī)會(huì)調(diào)整這些通道??偠灾@是一種非??崆覐?qiáng)大的顏色語(yǔ)法。

在下面的例子中,使用了相對(duì)顏色語(yǔ)法來(lái)創(chuàng)建基色的更亮和更暗的變體,并使用 color-contrast() 來(lái)確保標(biāo)簽具有適當(dāng)?shù)膶?duì)比度:


此函數(shù)也可用于調(diào)色板生成。這是一個(gè)例子,其中整個(gè)調(diào)色板是根據(jù)提供的基色生成的。這套 CSS 支持所有不同的調(diào)色板,每個(gè)調(diào)色板只是提供不同的基色。

: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);
}

到現(xiàn)在為止,希望你可以看到色彩空間和不同的色彩函數(shù)如何根據(jù)它們的優(yōu)點(diǎn)和缺點(diǎn)用于不同的目的。

相關(guān)資源:

Spec: https://www.w3.org/TR/css-color-5/#relative-color-function
Palettes: https://codepen.io/web-dot-dev/pen/GRybLvm
Variants: https://codepen.io/web-dot-dev/pen/dyJBLWG
(6)漸變顏色空間
在漸變顏色空間之前,sRGB 是使用的默認(rèn)顏色空間。sRGB 通常是可靠的,但確實(shí)有一些弱點(diǎn),例如灰色死區(qū)。


在漸變顏色空間之后,告訴瀏覽器使用哪個(gè)顏色空間進(jìn)行顏色插值。這使開(kāi)發(fā)人員和設(shè)計(jì)人員能夠選擇他們喜歡的漸變。默認(rèn)色彩空間也更改為 LCH 而不是 sRGB。

語(yǔ)法添加在漸變方向之后,使用新的in語(yǔ)法,并且是可選的:

background-image: linear-gradient(
  to right in hsl,
  black, white
);

background-image: linear-gradient(
  to right in lch,
  black, white
);
這是從黑色到白色的基本且必不可少的漸變。查看每個(gè)顏色空間中的結(jié)果范圍。有些更早達(dá)到深黑色,有些更晚達(dá)到白色。


在下一個(gè)示例中,黑色轉(zhuǎn)換為藍(lán)色,因?yàn)樗菨u變的已知問(wèn)題空間。大多數(shù)顏色空間在顏色插值期間會(huì)逐漸變?yōu)樽仙??;蛘?,?dāng)顏色在其顏色空間內(nèi)從 A 點(diǎn)移動(dòng)到 B 點(diǎn)時(shí)。由于漸變將從 A 點(diǎn)到 B 點(diǎn)采用直線,因此色彩空間的形狀變化極大地改變了路徑沿途的停止點(diǎn)。

okLCH 和 okLAB 是專門的色彩空間,可以解釋各種變化,比如這個(gè)變成紫色的,這使得它們對(duì)于漸變特別準(zhǔn)確。


相關(guān)資源:

Spec: https://drafts.csswg.org/css-images-4/#linear-gradients
Codepen comparing gradients: https://codepen.io/argyleink/pen/OJObWEW
Observable notebook: https://observablehq.com/@argyleink/colorjs-notebook-fade-to-white
7. inert
瀏覽器支持:


在 inert之前,將用戶的注意力引導(dǎo)到需要立即關(guān)注的頁(yè)面或應(yīng)用程序區(qū)域是一種很好的做法。這種引導(dǎo)式焦點(diǎn)策略被稱為焦點(diǎn)捕獲,因?yàn)殚_(kāi)發(fā)人員會(huì)將焦點(diǎn)置于交互空間中,監(jiān)聽(tīng)焦點(diǎn)更改事件,如果焦點(diǎn)離開(kāi)交互空間,則強(qiáng)制返回。使用鍵盤或屏幕閱讀器的用戶會(huì)被引導(dǎo)回到互動(dòng)空間,以確保在繼續(xù)完成之前的任務(wù)。

在inert之后,不需要設(shè)置陷阱,因?yàn)槟憧梢詢鼋Y(jié)或保護(hù)頁(yè)面或應(yīng)用程序的整個(gè)部分。當(dāng)文檔的這些部分處于惰性狀態(tài)時(shí),單擊和焦點(diǎn)更改嘗試根本不可用。你也可以把它想象成守衛(wèi)而不是陷阱,惰性分子不想讓你待在某個(gè)地方,而是讓其他地方不可用。

JavaScript alert() 函數(shù)就是一個(gè)很好的例子:


請(qǐng)注意,在調(diào)用 alert() 之前,頁(yè)面是如何通過(guò)鼠標(biāo)和鍵盤訪問(wèn)的。顯示警報(bào)對(duì)話框彈出窗口后,頁(yè)面的其余部分將被凍結(jié)或不活動(dòng)。用戶的注意力放在警報(bào)對(duì)話框中,無(wú)處可去。一旦用戶交互并完成警報(bào)功能請(qǐng)求,頁(yè)面將再次交互。inert使開(kāi)發(fā)人員能夠輕松實(shí)現(xiàn)同樣的引導(dǎo)焦點(diǎn)體驗(yàn)。

下面示例來(lái)展示它是如何工作的:

<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>
對(duì)話框是一個(gè)很好的例子,但inert也有助于諸如滑出式側(cè)邊菜單用戶體驗(yàn)之類的事情。當(dāng)用戶滑出側(cè)邊菜單時(shí),讓鼠標(biāo)或鍵盤與后面的頁(yè)面交互是不合適的;相反,當(dāng)顯示側(cè)邊菜單時(shí),使頁(yè)面處于inert狀態(tài),現(xiàn)在用戶必須關(guān)閉或在該側(cè)邊菜單中導(dǎo)航,并且永遠(yuǎn)不會(huì)發(fā)現(xiàn)自己在打開(kāi)菜單的頁(yè)面中迷失在其他地方。

相關(guān)資源:

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 字體,這也是一種開(kāi)放格式,用于漸變字體、內(nèi)置顏色和效果。不過(guò),它們可能會(huì)變得非常大,雖然它們?cè)试S編輯文本,但定制的空間不大。

在 COLRv1 字體之后,Web 具有更小的占用空間、矢量可縮放、可重新定位、漸變功能和混合模式驅(qū)動(dòng)的字體,它們接受參數(shù)來(lái)自定義每個(gè)用例的字體或匹配主題。


下面是 Chrome Developer 博客文章中有關(guān)表情符號(hào)的示例。也許你已經(jīng)注意到,如果你放大表情符號(hào)的字體大小,它就不會(huì)保持清晰。這是一個(gè)圖像,而不是矢量藝術(shù)。使用 COLRv1 字體,表情符號(hào)既矢量又漂亮:


圖標(biāo)字體可以用這種格式做一些驚人的事情,提供自定義的雙色調(diào)調(diào)色板等等。加載 COLRv1 字體就像任何其他字體文件一樣:

@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
自定義 COLRv1 字體使用 @font-palette-values 完成的,這是一個(gè)特殊的 CSS 規(guī)則,用于將一組自定義選項(xiàng)分組和命名為一個(gè)包以供以后參考。指定自定義名稱就像自定義屬性一樣,以 -- 開(kāi)頭:

@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 作為自定義的別名,最后一步是將調(diào)色板應(yīng)用于使用顏色字體系列的元素:

@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;
}

隨著越來(lái)越多的可變字體和彩色字體的出現(xiàn),網(wǎng)頁(yè)排版正朝著豐富的定制和創(chuàng)造性表達(dá)的方向發(fā)展。

相關(guān)資源:

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. 視口單位

在新的視口變體之前,web提供了物理單位來(lái)幫助適應(yīng)視口。有高度、寬度、最小尺寸 (vmin) 和最大邊 (vmax)。這些對(duì)很多事情都有效,但移動(dòng)瀏覽器帶來(lái)了復(fù)雜性。

在移動(dòng)設(shè)備上,加載頁(yè)面時(shí),會(huì)顯示帶有 url 的狀態(tài)欄,此欄會(huì)占用部分視口空間。在幾秒鐘和一些交互之后,狀態(tài)欄可能會(huì)滑開(kāi),以便為用戶提供更大的視口體驗(yàn)。但是當(dāng)該條滑出時(shí),視口高度發(fā)生了變化,任何 vh 單位都會(huì)隨著目標(biāo)大小的變化而移動(dòng)和調(diào)整大小。

在后來(lái)的幾年里,vh 單位特別需要決定要使用兩種視口尺寸中的哪一種,因?yàn)檫@會(huì)在移動(dòng)設(shè)備上造成不和諧的視覺(jué)布局問(wèn)題。已確定 vh 將始終代表最大的視口。

.original-viewport-units {
  height: 100vh;
  width: 100vw;
  --size: 100vmin;
  --size: 100vmax;
}
在新的視口變體之后,可以使用小型、大型和動(dòng)態(tài)視口單位,并在物理視口單元的基礎(chǔ)上添加邏輯等效單位。這個(gè)想法是讓開(kāi)發(fā)人員和設(shè)計(jì)人員能夠選擇他們想要在給定場(chǎng)景中使用的單位。

當(dāng)狀態(tài)欄消失時(shí),也許可以稍微改變一下不協(xié)調(diào)的布局,這樣就可以不用擔(dān)心使用dvh(動(dòng)態(tài)視口高度)。


以下是新視口變體提供的所有新視口單位選項(xiàng)的完整列表:

/* 高度視口單位 */
.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;
}
希望這些將為開(kāi)發(fā)人員和設(shè)計(jì)人員提供實(shí)現(xiàn)其視口響應(yīng)式設(shè)計(jì)所需的靈活性。

相關(guān)資源:

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()
瀏覽器支持:


在 :has() 之前,選擇器的主體總是在最后。例如,這個(gè)選擇器的主體是一個(gè)列表項(xiàng):ul > li。偽選擇器可以改變選擇器,但它們不會(huì)改變主體:ul > li:hover 或 ul > li:not(.selected)。

在 :has() 之后,元素樹(shù)中較高的主體可以保留為主體,同時(shí)提供有關(guān)子項(xiàng)的查詢:ul:has(> li)。很容易理解 :has() 是如何獲得“父選擇器”的通用名稱的,因?yàn)樵谶@種情況下,選擇器的主體現(xiàn)在是父級(jí)。

這是一個(gè)基本語(yǔ)法示例,其中 .parent 類仍然是主體,但僅在子元素具有 .child 類時(shí)才被選中:

.parent:has(.child) {...}
這是一個(gè)示例,其中 <section> 元素是主體,但選擇器僅在其中一個(gè)子元素具有 :focus-visible 時(shí)才匹配:

section:has(*:focus-visible) {...}
:has()選擇器開(kāi)始成為一個(gè)神奇的實(shí)用工具,因?yàn)閷?shí)際用例變得更加明顯。例如,當(dāng)前無(wú)法在包裝圖像時(shí)選擇<a>標(biāo)簽,因此很難確定錨定標(biāo)記在該用例中如何更改其樣式??梢允褂?:has() 實(shí)現(xiàn):

a:has(> img) {...}
這些都是 :has() 看起來(lái)像父選擇器的例子。如果圖片有 <figcaption>,請(qǐng)考慮 <figure> 元素內(nèi)圖像的用例和調(diào)整圖像的樣式。在以下示例中,選擇帶有 figcaptions 的圖像,然后選擇該上下文中的圖像。使用:has() 不會(huì)改變主體,因?yàn)槲覀兊哪繕?biāo)是圖像而不是數(shù)字:

figure:has(figcaption) img {...}
使用 @supports 及其 selector() 函數(shù)使檢查支持變得簡(jiǎn)單,該函數(shù)在使用之前測(cè)試瀏覽器是否支持該語(yǔ)法:

@supports (selector(:has(works))) {
  /* safe to use :has() */
}
相關(guān)資源:

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 年登陸之后,仍有許多事情將難以完成。下面來(lái)介紹一些剩余的問(wèn)題以及正在積極開(kāi)發(fā)的解決方案。這些解決方案是實(shí)驗(yàn)性的,即使它們可能在瀏覽器的標(biāo)志后面被指定或可用。

1. 松散類型的自定義屬性
瀏覽器支持:


CSS 自定義屬性是驚人的。它們?cè)试S將各種事物存儲(chǔ)在命名變量中,然后可以對(duì)其進(jìn)行擴(kuò)展、計(jì)算、共享等。事實(shí)上,它們是如此靈活,如果有一些不太靈活的東西會(huì)更好。

考慮一個(gè)場(chǎng)景,其中長(zhǎng)方體陰影使用自定義屬性作為其值:

box-shadow: var(--x) var(--y) var(--blur) var(--spread) var(--color);
這一切都會(huì)正常運(yùn)行,直到任何一個(gè)屬性更改為 CSS 不接受的值,例如 --x: red。如果任何一個(gè)嵌套變量丟失或設(shè)置為無(wú)效的值類型,則整個(gè)陰影會(huì)中斷。

這就是@property 的用武之地:--x 可以成為一個(gè)類型化的自定義屬性,不再松散和靈活,但在某些定義的邊界下是安全的:

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





現(xiàn)在,當(dāng) box-shadow 中的var(--x) 使用 --x: red 時(shí),red 將被忽略,因?yàn)樗皇?<length>。這意味著陰影會(huì)繼續(xù)正常工作,即使為其自定義屬性之一提供了無(wú)效值。它沒(méi)有失敗,而是恢復(fù)到其初始值 0px。

除了類型安全之外,它還為動(dòng)畫(huà)打開(kāi)了許多大門。CSS 語(yǔ)法的靈活性使得某些動(dòng)畫(huà)變得不可能,比如漸變。@property 在這里會(huì)很有用,因?yàn)轭愋突?CSS 屬性可以告知瀏覽器開(kāi)發(fā)人員在其他過(guò)于復(fù)雜的插值中的意圖。它本質(zhì)上限制了可能性的范圍,以至于瀏覽器可以為以前無(wú)法實(shí)現(xiàn)的樣式的各個(gè)方面設(shè)置動(dòng)畫(huà)。

考慮下面的例子,其中使用徑向漸變來(lái)制作覆蓋的一部分,從而創(chuàng)建聚光燈聚焦效果。按下alt/opt鍵時(shí),JavaScript設(shè)置鼠標(biāo)x和y,然后將焦點(diǎn)大小更改為較小的值,例如25%,在鼠標(biāo)位置創(chuàng)建聚光燈焦點(diǎn)圓:



.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%
  );
}
不過(guò),漸變無(wú)法設(shè)置動(dòng)畫(huà)。它們對(duì)于瀏覽器來(lái)說(shuō)太靈活和太復(fù)雜了,無(wú)法理解你希望它們?nèi)绾沃谱鲃?dòng)畫(huà)。但是,使用@property,可以單獨(dú)設(shè)置一個(gè)屬性并為其設(shè)置動(dòng)畫(huà),瀏覽器可以輕松理解其意圖。

使用這種聚焦效果的電子游戲始終會(huì)為圓設(shè)置動(dòng)畫(huà),從一個(gè)大圓到一個(gè)針孔圓。下面是如何在演示中使用@property,以便瀏覽器為漸變遮罩設(shè)置動(dòng)畫(huà):

@property --focal-size {
  syntax: '<length-percentage>';
  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;
}
瀏覽器現(xiàn)在能夠?yàn)闈u變大小設(shè)置動(dòng)畫(huà),因?yàn)槲覀円褜⑿薷牡谋砻娣e減少到只有一個(gè)屬性并設(shè)置值,以便瀏覽器可以智能地插入長(zhǎng)度。

相關(guān)資源:

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 來(lái)表達(dá)條件。它可能看起來(lái)像這樣:

@media (min-width: 320px) {
  …
}
在媒體查詢范圍之后,相同的媒體查詢可能如下所示:

@media (320px >= width) {
  …
}
使用 min-width 和 max-width 的 CSS 媒體查詢可能如下所示:

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

在媒體查詢范圍之后,相同的媒體查詢可能如下所示:

@media (320px <= width <= 1280px) {
  …
}
后者看起來(lái)會(huì)比前者更清晰。由于規(guī)范的增加,開(kāi)發(fā)人員將能夠選擇他們喜歡的,甚至可以互換使用它們。

相關(guān)資源:

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 之前,媒體查詢必須一次又一次地重復(fù),或者依賴預(yù)處理器在構(gòu)建期間基于靜態(tài)變量生成正確的輸出。

在@custom-media 之后,CSS允許對(duì)媒體查詢進(jìn)行定義別名和引用,就像自定義屬性一樣。

命名非常重要:它可以使目的與語(yǔ)法保持一致,使事物更易于共享,更易于在團(tuán)隊(duì)中使用。以下是一些自定義媒體查詢:

@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);
現(xiàn)在它們已定義,我可以像這樣使用其中一個(gè):

@media (--OSdark) {
  :root {
    …
  }
}
相關(guān)資源

Spec: https://www.w3.org/TR/mediaqueries-5/#custom-mq
PostCSS plugin: https://github.com/postcss/postcss-custom-media
4. 嵌套選擇器
在 @nest之前,樣式表中有很多重復(fù)。當(dāng)選擇器很長(zhǎng)且每個(gè)選擇器都針對(duì)微小的差異時(shí),它變得特別笨拙。所以,我們會(huì)經(jīng)常使用預(yù)處理器的嵌套功能。

在 @nest 之后,重復(fù)就消失了。幾乎所有支持預(yù)處理器的嵌套功能都將內(nèi)置在 CSS 中。

article {
  color: darkgray;
}

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

/* with @nest becomes */

article {
  color: darkgray;

  & > a {
    color: var(--link-color);
  }
}
除了避免重復(fù)的代碼,嵌套最重要的是樣式上下文保留在一個(gè)樣式塊中。讀者無(wú)需從一個(gè)選擇器及其樣式跳到另一個(gè)帶有樣式的選擇器(示例 1),而是可以留在文章的上下文中并查看文章在其中擁有鏈接。

考慮一個(gè)子組件,它希望在不同的父級(jí)上下文中調(diào)整自己,而不是父組件擁有樣式并更改子組件:

/* 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 總體上有助于更健康的風(fēng)格組織、集中化和所有權(quán)。組件可以分組并擁有自己的樣式,而不是讓它們散布在其他樣式塊中。在這些示例中,它可能看起來(lái)很小,但為了方便和易讀性,它可以產(chǎn)生非常大的影響。

相關(guān)資源:

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 之前,存在許多策略,因?yàn)?CSS 中的樣式在默認(rèn)情況下是級(jí)聯(lián)、繼承和全局作用域的。CSS 的這些特性在很多方面都非常方便,但對(duì)于復(fù)雜的站點(diǎn)和應(yīng)用程序,可能有許多不同樣式的組件,級(jí)聯(lián)的全局空間和性質(zhì)會(huì)使樣式感覺(jué)像是在泄漏。

在 @scope 之后,樣式不僅可以限定在一個(gè)上下文中,就像一個(gè)類一樣,它們還可以明確樣式的結(jié)束位置,并且不會(huì)繼續(xù)級(jí)聯(lián)或繼承。

在以下示例中,BEM 命名約定范圍可以轉(zhuǎn)換為實(shí)際意圖。BEM 選擇器試圖將 header 元素的顏色范圍限定為具有命名約定的 .card 容器。這要求header上有這個(gè)類名,從而完成目標(biāo)。使用 @scope,無(wú)需命名約定即可在不標(biāo)記header元素的情況下完成相同的目標(biāo):

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

/* with @scope becomes */

@scope (.card) {
  header {
    color: var(--text);
  }
}
下面是另一個(gè)例子,不特定于組件,更多的是關(guān)于 CSS 的全局范圍性質(zhì)。深色和淺色主題必須在樣式表中共存,其中順序在確定獲勝風(fēng)格時(shí)很重要。通常這意味著深色主題樣式出現(xiàn)在淺色主題之后;這將淺色設(shè)置為默認(rèn)樣式,將深色設(shè)置為可選樣式。避免與 @scope的排序和范圍之爭(zhēng):

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

@scope (.dark-theme) {
  a { color: plum; }
}
@scope 還允許建立樣式范圍的結(jié)束位置。這不能通過(guò)任何命名約定或預(yù)處理器來(lái)完成;它很特別,只有瀏覽器內(nèi)置的 CSS 才能做到。在以下示例中,當(dāng) .media-block 的子項(xiàng)是 .content 的兄弟或父項(xiàng)時(shí),將專門應(yīng)用 img 和 .content 樣式:

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

  .content {
    padding: 1em;
  }
}
相關(guān)資源:

Spec: https://www.w3.org/TR/css-scoping-1/
Explainer: https://css.oddbird.net/scope/explainer/
6. 瀑布流布局
在使用Grid實(shí)現(xiàn)CSS瀑布流布局之前,JavaScript是實(shí)現(xiàn)瀑布流布局的最佳方式,因?yàn)槿魏螏в辛谢騠lexbox的CSS方法都會(huì)不準(zhǔn)確地表示內(nèi)容順序。使用grid構(gòu)建CSS后,將不需要JavaScript庫(kù),內(nèi)容順序也將正確。


上圖使用以下 CSS 實(shí)現(xiàn):

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}
相關(guān)資源:

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保存數(shù)據(jù)
在 prefers-reduced-data媒體查詢之前,JavaScript 和服務(wù)器可以根據(jù)用戶的操作系統(tǒng)或?yàn)g覽器的“data saver”選項(xiàng)更改其行為,但 CSS 不能。

在 prefers-reduced-data 媒體查詢之后,CSS 可以加入用戶體驗(yàn)增強(qiáng),并在保存數(shù)據(jù)方面發(fā)揮作用。

@media (prefers-reduced-data: reduce) {
  picture, video {
    display: none;
  }
}
在這個(gè)媒體滾動(dòng)組件中使用了前面的CSS,節(jié)省了很多資源。根據(jù)訪問(wèn)視口的大小,可以在頁(yè)面加載上節(jié)省更多資源。當(dāng)用戶與媒體滾動(dòng)條交互時(shí),繼續(xù)保存。這些圖像上都有l(wèi)oad="lazy"屬性,再加上CSS完全隱藏元素,這意味著永遠(yuǎn)不會(huì)對(duì)圖像發(fā)出網(wǎng)絡(luò)請(qǐng)求。


對(duì)于我的測(cè)試,在一個(gè)中等大小的視口上,最初加載了 40 個(gè)請(qǐng)求和 700kb 的資源。當(dāng)用戶滾動(dòng)媒體選擇時(shí),會(huì)加載更多請(qǐng)求和資源。使用 CSS prefers-reduced-data媒體查詢,加載了 10 個(gè)請(qǐng)求和 172kb 的資源。這節(jié)省了半兆字節(jié),用戶甚至沒(méi)有滾動(dòng)任何媒體,此時(shí)沒(méi)有其他請(qǐng)求。


這種減少數(shù)據(jù)體驗(yàn)的優(yōu)勢(shì)不僅僅是節(jié)省資源??梢钥吹礁鄻?biāo)題,并且沒(méi)有分散注意力的封面圖片來(lái)吸引注意力。許多用戶在數(shù)據(jù)保護(hù)模式下瀏覽,因?yàn)樗麄儼疵空鬃止?jié)的數(shù)據(jù)付費(fèi)——很高興看到 CSS 能夠在這里提供幫助。

相關(guān)資源:

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. 滾動(dòng)快照
在這些滾動(dòng)快照提案之前,需要編寫(xiě)自己的 JavaScript 來(lái)管理輪播、滑塊或圖庫(kù),并且可能會(huì)很復(fù)雜,需要所有的觀察者和狀態(tài)管理。此外,如果不小心,自然滾動(dòng)速度可能會(huì)被腳本標(biāo)準(zhǔn)化,使用戶交互感覺(jué)有點(diǎn)不自然并且可能很笨拙。

(1)snapChanging()
瀏覽器一發(fā)布快照子項(xiàng),就會(huì)觸發(fā)此事件。這允許用戶界面反映缺少快照子項(xiàng)和滾動(dòng)條的不確定快照狀態(tài),因?yàn)樗F(xiàn)在正在使用,并將在新的地方落地。

document.querySelector('.snap-carousel').addEventListener('snapchanging', event => {
  console.log('Snap is changing', event.snappedTargetsList);
});
(2)snapChanged()
一旦瀏覽器捕捉到一個(gè)新的子對(duì)象,滾動(dòng)條停止,就會(huì)觸發(fā)此事件。這使得任何依賴于快照子對(duì)象的UI都可以更新并反映連接。

document.querySelector('.snap-carousel').addEventListener('snapchanged', event => {
  console.log('Snap changed', event.snappedTargetsList);
});
(3)scroll-start
滾動(dòng)并不總是從一開(kāi)始就開(kāi)始??紤]一下可滑動(dòng)組件,其中向左或向右滑動(dòng)會(huì)觸發(fā)不同的事件,或者頁(yè)面加載時(shí)的搜索欄最初是隱藏的,直到滾動(dòng)到頂部。這個(gè)CSS屬性允許開(kāi)發(fā)者指定一個(gè)滾動(dòng)條應(yīng)該從一個(gè)特定的點(diǎn)開(kāi)始。

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

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
(4):snap-target
這個(gè) CSS 選擇器將匹配滾動(dòng)捕捉容器中當(dāng)前被瀏覽器捕捉的元素。

.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;
}
在這些滾動(dòng)快照提案之后,制作滑塊、輪播或圖庫(kù)要容易得多,因?yàn)闉g覽器現(xiàn)在為任務(wù)提供了便利,消除了觀察者和滾動(dòng)編排代碼,有利于使用內(nèi)置 API。

這些 CSS 和 JS 功能還處于早期階段,但請(qǐng)留意可以幫助盡快采用和測(cè)試它們的 polyfill。

相關(guān)資源:

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狀態(tài)
在 toggle()之前,只有瀏覽器內(nèi)置的狀態(tài)才能用于樣式和交互。例如,復(fù)選框輸入具有 :checked,這是一種內(nèi)部管理的瀏覽器狀態(tài),用于 CSS 能夠用于視覺(jué)更改元素的輸入。

在 toggle() 之后,可以在任何元素上創(chuàng)建自定義狀態(tài),以便 CSS 更改和用于樣式。它允許循環(huán)、定向切換等。

在以下示例中,實(shí)現(xiàn)了與完整列表項(xiàng)刪除線相同的效果,但沒(méi)有任何復(fù)選框元素:

<ul class='ingredients'>
  <li>1 banana
  <li>1 cup blueberries
    ...
</ul>
以及相關(guān)的 CSS toggle() 樣式:

li {
  toggle-root: check self;
}

li:toggle(check) {
  text-decoration: line-through;
}
如果你熟悉狀態(tài)機(jī),可能會(huì)注意到 toggle() 有多少交叉。這個(gè)特性將讓開(kāi)發(fā)人員將更多的狀態(tài)構(gòu)建到 CSS 中,希望能以更清晰、更語(yǔ)義化的方式來(lái)編排交互和狀態(tài)。

相關(guān)資源:

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. 自定義選擇元素
在 <selectmenu> 之前,CSS 無(wú)法使用豐富的 HTML 自定義 <option> 元素或更改選項(xiàng)列表的顯示方式。這導(dǎo)致開(kāi)發(fā)人員加載外部庫(kù),這些庫(kù)重新創(chuàng)建了 <select> 的大部分功能,這最終導(dǎo)致了大量工作。

在 <selectmenu> 之后,開(kāi)發(fā)人員可以為選項(xiàng)元素提供豐富的 HTML,并根據(jù)需要對(duì)其進(jìn)行樣式設(shè)置,同時(shí)仍然滿足可訪問(wèn)性要求并提供語(yǔ)義 HTML。

在以下示例中,取自 <selectmenu> 解釋器頁(yè)面,創(chuàng)建了一個(gè)帶有一些基本選項(xiàng)的新選擇菜單:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>
CSS可以針對(duì)元素的各個(gè)部分并設(shè)置其樣式:

.my-select-menu::part(button) {
  color: white;
  background-color: red;
  padding: 5px;
  border-radius: 5px;
}

.my-select-menu::part(listbox) {
  padding: 10px;
  margin-top: 5px;
  border: 1px solid red;
  border-radius: 5px;
}

相關(guān)資源:

Spec: https://open-ui.org/prototypes/selectmenu
Demo: https://microsoftedge.github.io/Demos/selectmenu/
11. 定位
在 anchor() 之前,絕對(duì)位置和相對(duì)位置是為開(kāi)發(fā)人員提供的位置策略,可以讓子元素在父元素中移動(dòng)。

在 anchor() 之后,開(kāi)發(fā)人員可以將元素定位到其他元素,無(wú)論它們是否是子元素。它還允許開(kāi)發(fā)人員指定要定位的邊緣,以及創(chuàng)建元素之間位置關(guān)系的其他細(xì)節(jié)。

相關(guān)資源:

Explainer: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/CSSAnchoredPositioning/explainer.md
來(lái)源:https://web.dev/state-of-css-2022


歡迎關(guān)注微信公眾號(hào) :前端開(kāi)發(fā)愛(ài)好者


添加好友備注【進(jìn)階學(xué)習(xí)】拉你進(jìn)技術(shù)交流群