CSS 2022 現況

自 2022 年 Google IO 大會所見,現在與明日的網路樣式功能,還有一些額外功能。

2022 年度是 CSS 最偉大的一年之一,不僅涵蓋功能和協作式瀏覽器功能發布,我們的目標更是共同推出 14 項功能!

總覽

這篇文章是 Google IO 2022 年發布的演講內容。與其提供各項功能的詳盡指南,如果你有興趣,可參考章節結尾的資源連結,取得更多資訊。

目錄

請使用下方清單跳到您感興趣的主題:

瀏覽器相容性

許多 CSS 功能必須配合發布,主要是因為 2022 年互通性的緣故。在研究互通性工作之前,請務必查看 Compat 2021 的努力。

2021 年 Compat 報告

根據開發人員透過問卷調查的意見回饋,2021 年的目標是維持目前功能、改善測試套件,以及增加五項功能的瀏覽器通過分數:

  1. sticky 定位
  2. aspect-ratio大小
  3. flex」版面配置
  4. grid」版面配置
  5. transform 定位和動畫

全面提升測試分數的表現,展現提升的穩定性和可靠性。恭喜各位!

2022 年互通性

今年,瀏覽器會一起討論他們期望開發的功能和優先順序,將努力都整合在一起。並打算為開發人員提供下列網頁功能:

  1. @layer
  2. 色域和函式
  3. 遏制
  4. <dialog>
  5. 表單相容性
  6. 捲動
  7. 子網格
  8. 字體排版
  9. 可視區域單元
  10. 網頁相容性

這份令人期待的新奇亮眼成績,我迫不及待想看到具體結果。

2022 年更新

不出所料,CSS 2022 的狀態受到 Interop 2022 工作影響。

串聯圖層

瀏覽器支援

  • 99
  • 99
  • 97
  • 15.4

資料來源

@layer 之前,發現的樣式表載入順序非常重要,因為上次載入的樣式可能會覆寫先前載入的樣式。這形成了易於管理的輸入樣式表,開發人員需要先載入較不重要的樣式,之後再載入更重要的樣式。可以透過完整的方法協助開發人員管理重要性,例如 ITCSS

使用 @layer 時,項目檔案可以預先定義圖層及其順序。接著,載入或定義樣式時,可放置在圖層中,以便保存樣式覆寫的重要性,但沒有複雜的管理載入自動化調度管理。

影片說明定義的層疊層如何提供更自由且自由樣式的編寫和載入程序,同時視需要維持串接。

Chrome 開發人員工具可協助您以視覺化的方式瞭解下列圖層來源:

Chrome 開發人員工具的「樣式」側欄螢幕截圖,醒目顯示樣式在新「圖層」群組中的顯示方式。

資源

子網格

瀏覽器支援

  • 117
  • 117
  • 71
  • 16

資料來源

subgrid 之前,其他格狀檢視畫面中的格線無法與父項儲存格或格線對齊。每個格狀版面配置都不重複。許多設計人員會在整個設計上放置單一格線,並會持續對齊其中項目,這在 CSS 中無法實現。

subgrid 之後,格線的子項可以採用其父項資料欄或資料列做為自身,並將其本身或子項對齊!

在以下示範中,內文元素會建立含有三個資料欄的傳統版格線:中間資料欄稱為 main,左側欄和右側資料欄則為其線條 fullbleed。接著,透過設定 grid-template-columns: subgrid,主體中的每個元素 (<nav><main>) 採用主體中的具名行。

​​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> 的子項可以使用 fullbleedmain 資料欄和線條,自行對齊或調整其大小。

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

.fullbleed {
  grid-column: fullbleed;
}

開發人員工具可顯示幾行程式碼和次網格 (目前僅 Firefox)。 在下圖中,父項格線和子網格已重疊。現在,外觀類似於設計人員對於版面配置的思考。

子網格示範畫面的螢幕截圖,使用 Chrome 開發人員工具疊加層疊加工具,顯示 CSS 定義的線條。

在開發人員工具的元素面板中,您可以查看哪些元素是格線和子格線,對於偵錯或驗證版面配置非常實用。

Chrome 開發人員工具的「Elements」面板螢幕截圖,標明哪些元素具有格線或子格狀版面配置。
Firefox 開發人員工具的螢幕截圖

資源

容器查詢

瀏覽器支援

  • 105
  • 105
  • 110
  • 16

資料來源

@container 之前,網頁的元素只能回應整個可視區域的大小。這種做法適合巨集版面配置,但在微版面配置中,如果其外容器並非整個可視區域,則版面配置無法據此調整。

@container 之後,元素可以回應父項容器大小或樣式!唯一要注意的是,容器必須宣告自己為可能的查詢目標,這是一項可獲取龐大利益的一小部分要求。

/* establish a 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;
  }
}

以下再舉例說明:某個書籍元件會配合拖曳目標資料欄中的可用空間調整內容:

示範

以「新回應」的形式評估,Una 的正確性。使用 @container 時,您需要做出許多令人期待且有意義的設計決策。

資源

accent-color

瀏覽器支援

  • 93
  • 93
  • 92
  • 15.4

資料來源

accent-color 之前,如果您想建立具有品牌相符顏色的表單,可能會使得隨著時間變得難以管理的複雜程式庫或 CSS 解決方案。雖然他們提供所有選項,且希望能納入無障礙設計,但要選擇使用內建元件或採用自己的元件,就必須選擇此選項,才能做出選擇。

accent-color 之後,任一行 CSS 會為內建元件提供品牌顏色。除了色調之外,瀏覽器會聰明地為元件的附屬部分選擇適當的對比顏色,並根據系統色彩配置 (淺色或深色)。

/* tint everything */
:root {
  accent-color: hotpink;
}

/* tint one element */
progress {
  accent-color: indigo;
}

並排顯示淺色和深色的 HTML 元素,方便您進行比較。

如要進一步瞭解 accent-color,請前往 web.dev 查看文章,並在其中探索這個實用 CSS 屬性的更多相關資訊。

資源

顏色層級 4 和 5

過去數十年來,網路一直是 sRGB 的主要原因,但在拓展高畫質螢幕和配備 OLED 或 QLED 螢幕的行動裝置上,SRGB 仍是不夠的。此外,一般來說,網頁會配合使用者偏好設定進行調整,而顏色管理也一直在為設計人員、設計系統和程式碼維護者有所顧慮。

但在 2022 年之前,CSS 推出數種全新色彩功能和空格: - 可觸及螢幕 HD 高畫質色彩功能的顏色。 - 比對意圖的色彩空間,例如感知一致性。 - 漸層色彩空間會大幅改變內插結果。 - 顏色函式可協助您混合和對比,以及選擇要執行工作的空間。

在使用所有色彩特徵之前,設計系統需要預先計算適當的對比色彩,並確保正確調色盤,同時預先處理工具或 JavaScript 則能完成繁重的工作。

完成上述所有色彩功能之後,瀏覽器和 CSS 就能即時且即時地完成所有工作。CSS 可以進行編排和計算,不需要向使用者傳送許多 KB 的 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);
  }
}

hwb()

瀏覽器支援

  • 101
  • 101
  • 96
  • 15

資料來源

HWB 代表色調、白色和黑色。這種模型本身是一種色調,讓自己能理解色彩,提供非常容易理解的色彩。混音為白色或黑色的藝人 可能會感受到顏色語法的加分效果

使用這個色彩函式會產生 sRGB 色域的顏色,與 HSL 和 RGB 相同。就 2022 年的新進展而言,這項更新並未提供新的色彩,但可能會讓語法和心理模型的粉絲更容易處理某些工作。

資源

色域

顏色的表示方式是以色域完成。每個色域都具備各種特徵,並針對顏色作業做出取捨。有些可能會將所有明亮的顏色放在一起;有些可能會根據亮度進行對齊。

2022 年 CSS 將提供 10 個新的顏色空間,每個顏色空間都各具特色,方便設計人員和開發人員顯示、挑選及混色。先前,sRGB 是處理顏色的唯一選項,現在 CSS 也帶來全新的預設色彩空間,以及新的預設色彩空間 LCH。

color-mix()

瀏覽器支援

  • 111
  • 111
  • 113
  • 16.2

資料來源

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

以下為使用 color-mix() 的主題示範。請嘗試變更品牌顏色,並觀察主題更新的情形:

2022 年,歡迎在樣式表中盡情運用各種顏色空間!

資源

color-contrast()

瀏覽器支援

  • x
  • x
  • x

資料來源

color-contrast() 之前,樣式表作者必須事先瞭解無障礙顏色。通常調色盤會在色塊上顯示黑色或白色文字,向色彩系統使用者指出需要哪種文字顏色才能與色塊產生適當對比。

3 種 Material 調色盤的螢幕截圖,顯示 14 種顏色,以及適用於文字的白色或黑色對比色。
2014 年質感設計調色盤的範例

超過 color-contrast() 後,樣式表作者就能將工作完全卸載至瀏覽器。您不僅可以使用瀏覽器自動挑選黑色或白色,還能為設計系統提供適當顏色的清單,讓它先挑選想要的對比度。

以下螢幕截圖是 HWB 調色盤集示範的螢幕截圖,其中顯示瀏覽器根據色塊顏色自動選擇的文字顏色:

HWB 示範的螢幕截圖,其中每個調色盤具有不同的淺色或深色文字組合 (由瀏覽器決定)。
試用示範

語法的基本概念如下所示,其中灰色會傳遞至函式,而瀏覽器會判斷黑色或白色的對比度是否最高:

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 語言本身內建適當的對比色選項後,如果要提供方便易用的介面,會有多容易。

資源

相對色彩語法

瀏覽器支援

  • 111
  • 111
  • 113
  • 15

資料來源

在使用相對色彩語法之前,如要針對顏色進行計算及調整,需要個別放置在自訂屬性中的色彩管道。這項限制也使 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() 確保標籤具有適當的對比度:

有 3 欄的螢幕截圖,每一欄都比中央資料欄更暗或更亮。
試用示範

這個函式也可用於產生調色盤。以下範例是用所提供的基本顏色產生整個調色盤。這組 CSS 支援各種調色盤,每個調色盤只會提供不同的基礎。此外,由於我使用 LCH,因此多虧了 LCH,因此看來即使是調色盤的感覺,也沒有太多熱點或致死的地方。

: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);
}
15 個調色盤的螢幕截圖,這些調色盤由 CSS 動態產生。
試用示範

希望現在您可以看到色彩空間和不同的色彩函式如何根據其優點和弱點用於不同目的。

資源

漸層色空間

在漸層色彩空間之前,sRGB 是預設的色彩空間。sRGB 通常可靠,但有一些弱點,例如「灰色無效區域」

在格狀版面中呈現 4 種漸層,全部從青色到深粉紅。LCH 和 LAB 的色彩更一致,其中 sRGB 中間會較為不飽和。

漸層色域後,請告知瀏覽器要用於色彩內插的色域。這可讓開發人員和設計人員選擇偏好的漸層。預設色域也會變更為 LCH,而非 sRGB。

新增的語法在漸層方向後方會新增 in 語法,且為選用項目:

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

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

以下為從黑白到白的基本漸層。請查看每個色彩空間的結果範圍。有些範圍較早進入深黑色 有些範圍太晚了

顯示比較黑色與白色的 11 個色域。

在下一個範例中,黑色會變成藍色,因為這是漸層的已知問題空間。在色彩內插期間,大多數的色域都會變成紫色,也如同我喜歡的,因為顏色會在從點 A 點到 B 點在顏色空間中傳遞。由於漸層會從 A 點到 B 點形成直線,因此色域的形狀會大幅改變路徑沿途的停靠點。

比較藍色與黑色的 11 個色域。

如需深入瞭解探索、範例和留言,請參閱這個 Twitter 執行緒

資源

inert

瀏覽器支援

  • 102
  • 102
  • 112
  • 15.5

資料來源

inert 之前,建議將使用者的焦點引導至需要立即註意的網頁或應用程式區域。由於開發人員會把焦點放在互動空間,監聽焦點變更事件,如果焦點離開互動空間,這種引導式策略就被稱為「聚焦」陷阱。鍵盤或螢幕閱讀器的使用者會引導回互動空間,確保工作在繼續執行前已完成。

inert 之後,由於可以凍結或保護頁面或應用程式的整個部分,因此無須複製作業。僅在文件的這些部分不穩定時,無法執行點選和焦點變更嘗試。使用者也可以想成是警戒而非陷阱,因為 inert 不會不想讓您停在其他地方,反而造成無法停留在其他地方。

JavaScript alert() 函式就是一個很好的例子:

網站顯示為互動式,然後呼叫 alert() 後,該網頁已失效。

請注意,在上一部影片中,在呼叫 alert() 之前,頁面是滑鼠和鍵盤可存取的方式。快訊對話方塊彈出式視窗顯示後,頁面中的其餘部分即會凍結 (或 inert)。使用者的焦點會放在快訊對話方塊中,而現在不在其他位置。使用者完成互動並完成快訊函式要求後,頁面就會再次進行互動。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 也對於滑出側邊選單使用者體驗等用途也有所幫助。使用者滑出側邊選單時,不能讓滑鼠或鍵盤與背後的網頁互動,這對使用者來說是一大挑戰。而是當顯示側邊選單時,請對頁面進行斷言,現在使用者必須關閉側邊選單或進行瀏覽,而且不會因為開啟了選單,而使得自己忘記放在頁面上其他位置。

資源

COLRv1 字型

在使用 COLRv1 字型之前,網路上也有 OT-SVG 字型,也是使用漸層和內建色彩與效果的開放式字型格式。不過,這些模組可能會變得非常龐大,雖然讓他們能夠編輯文字,但這樣做不太符合自訂範圍。

在採用 COLRv1 字型之後,網路佔用空間較小、向量可擴充、可調整位置、梯度下降功能,以及採用混合模式 (Blend-mode) 字型的字型,這些字型接受可依用途自訂字型或符合品牌的參數。

比較圖表和長條圖,顯示 COLRv1 字型的銳利化及更小。
圖片來源:https://developer.chrome.com/blog/colrv1-fonts/

以下是 Chrome 開發人員網誌文章有關表情符號的範例。也許您注意到,放大表情符號的字型大小,並不會保持清晰。這是圖片而非向量藝術。在應用程式中使用表情符號時,通常會替換為品質較高的素材資源。使用 COLRv1 字型時,表情符號是向量且精美:

圖示字型可透過這種格式發揮一些驚人效果,提供自訂雙色調調色盤等。載入 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;
}
包含「DUNE」文字的 Bungee Spice 字型螢幕截圖。
使用自訂顏色的 Bungee Spice 字型,來源:https://developer.chrome.com/blog/colrv1-fonts/

隨著越來越多的字型和色彩字型可供使用,網頁字體排版已成為打造豐富自訂和創意表現的一大利器。

資源

可視區域單元

圖片:裝置畫面、瀏覽器視窗和 iframe 各有不同的可視區域。

在新的可視區域變化版本之前,網站提供了實體單元來協助調整可視區域。包括高度、寬度、最小尺寸 (vmin) 及最大側邊 (vmax)。這些功能在許多情況下都能正常運作 但行動瀏覽器變得相當複雜

在行動裝置上,載入網頁時,會顯示內含網址的狀態列,且此列會佔用部分可視區域空間。經過幾秒後,狀態列可能會滑開,以便為使用者提供更大的可視區域體驗。但當該長條滑出時,可視區域的高度有所變更,且所有 vh 單位都會隨著目標大小改變及調整大小。後幾年,vh 單位特別需要決定要使用的兩個可視區域大小,因為這個單位會在行動裝置上造成視覺版面配置問題。我們判定 vh 一律會代表最大的可視區域。

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

新的可視區域變化版本推出後,您就可以使用小型、大型和動態可視區域單元,並在實體中加入邏輯對等單元。其概念是讓開發人員和設計人員能夠針對自己的情境選擇要使用的單位。也許在狀態列停止時,系統可以稍微擺動版面配置位移,因此可以放心使用 dvh (動態可視區域高度)。

圖中有三支手機,有助於描繪 DVH、LVH 和 SVH。DVH 範例手機有兩條垂直線,一條介於搜尋列底部和可視區域底部之間,以及搜尋列上方 (系統狀態列下方) 至可視區域底部之間。DVH 長度為這兩種長度之一。LVH 顯示在中間,裝置狀態列底部與手機可視區域按鈕之間有一條線。最後一個是 SVH 單元範例,其中一行顯示從瀏覽器搜尋列底部到可視區域底部

以下列出新版可視區域變化版本提供的所有新可視區域單元選項:

高度可視區域單元
​​.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;
}

希望這些做法能讓開發人員和設計人員彈性調整,以達到可視區域回應式設計。

資源

:has()

瀏覽器支援

  • 105
  • 105
  • 121
  • 15.4

資料來源

:has() 之前,選取器主旨一律位於結尾。例如,這個選取器的主旨是清單項目:ul > li。虛擬選取器可以變更選取器,但不會改變主旨:ul > li:hoverul > li:not(.selected)

:has() 之後,位於元素樹狀結構中較高位置的主體可以保留,同時提供子項查詢:ul:has(> li)。因為在這個例子中,選取器的主體現在是父項,因此很容易瞭解 :has() 如何取得「父項選取器」的通用名稱。

以下提供基本語法範例,其中 .parent 類別仍是主題,但只有在子項元素具有 .child 類別時才會選取:

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

以下示例中的 <section> 元素是主體,但只有在其中一個子項有 :focus-visible 時,選取器才會相符:

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

一旦更多實用的用途變得更加明顯,:has() 選取器就開始成為絕佳的實用性。舉例來說,目前無法在包裝圖片時選取 <a> 標記,導致錨點標記在這個用途中很難變更樣式。雖然 :has() 可能發生這種情況:

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

這些都屬於範例,其中 :has() 只類似父項選取器。考量 <figure> 元素中的圖片用途,如果圖表包含 <figcaption>,請調整圖片的樣式。在以下範例中,系統會選取含有 fig 說明文字的圖形,然後是該結構定義內的圖片。使用 :has() 且不會變更主題,因為指定的主題並非圖片:

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

這些組合看來還有無數的組合。結合 :has()數量查詢,並根據子項數量調整 CSS 格線版面配置。結合 :has()互動式虛擬類別狀態,並建立以新穎方式回應的應用程式。

使用 @supportsselector() 函式即可輕鬆檢查支援,藉此測試瀏覽器是否瞭解語法後再使用:

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

資源

2022 年以後

等到所有令人驚豔的功能於 2022 年推出後,還有一些事情將難以實現。下一節將介紹一些剩餘的問題,以及我們正在積極開發來解決這些問題的解決方案。這些解決方案雖然是實驗性質,但可能透過瀏覽器旗標加以指定或可用。

後續各節的收穫,應可以放心,其中列出的問題足以讓許多公司尋求解決辦法,而不是這些解決方案將在 2023 年推出。

過於寬鬆的自訂屬性

瀏覽器支援

  • 85
  • 85
  • 16.4

資料來源

CSS 自訂屬性非常棒。這些物件允許將各種事物儲存在已命名的變數中,然後就能擴充、計算、分享等等。事實上,這類容器的靈活性很高,要是能某些較缺乏彈性,會比較好。

假設以下情況:box-shadow 使用自訂屬性做為值:

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

在任一屬性變更為 CSS 不接受的值 (例如 --x: red) 之前,這個做法都能正常運作。缺少任一巢狀變數或設為無效的值類型時,整個陰影會中斷。

這時 @property 就能派上用場:--x 可成為型別的自訂屬性,不再寬鬆且沒有彈性,但可透過某些定義的邊界保護自身安全:

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

現在,當 box-shadow 使用 var(--x) 且稍後嘗試 --x: red 時,系統會忽略 red,因為其並非 <length>。這表示即使其中一個自訂屬性具備無效值,陰影仍會繼續運作。不會失敗,而是會還原為 0pxinitial-value

動畫

除了打字安全之外,播放動畫的門面也是開啟的。CSS 語法的靈活性會使某些內容無法以動畫方式呈現,例如漸層。@property 在這方面很有幫助,因為類型的 CSS 屬性可讓瀏覽器得知開發人員的意圖,其中含有過於複雜的內插作業。基本上,它會限制瀏覽器無法針對某個樣式建立動畫效果的可能性。

我們參考這個示範示例,使用放射漸層作為重疊的一部分,建立聚光焦點效果。按下 Alt/opt 鍵時,JavaScript 會設定滑鼠 x 和 y,然後將焦點變更為較小的值 (例如 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: '<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;
}
試用示範

瀏覽器現在可以為漸層大小建立動畫效果,因為我們已將修改的介面區域縮減為單一屬性,並輸入值,讓瀏覽器能巧妙插入長度。

@property 還有更多功能,但這些小型啟用可大幅改善。

資源

曾造訪min-widthmax-width

在媒體查詢範圍之前,CSS 媒體查詢會使用 min-widthmax-width 在條件下進行查詢。畫面可能會如下所示:

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

在媒體查詢範圍結束後,同一個媒體查詢看起來可能像這樣:

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

同時使用 min-widthmax-width 的 CSS 媒體查詢可能如下所示:

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

在媒體查詢範圍結束後,同一個媒體查詢看起來可能像這樣:

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

視程式設計背景而定,其中之一看起來會比另一個背景更加清晰。隨著規格新增,開發人員能夠選擇想要的項目,甚至可以交替使用。

資源

沒有任何媒體查詢變數

@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 {
    …
  }
}

您可以在 CSS 自訂屬性庫的「開啟屬性」中找到自訂媒體查詢的完整清單

資源

巢狀選取器功能很棒

@nest 之前,樣式表中有許多重複項目。當選取器過長,且每個目標鎖定的差距很小時,就顯得特別不易。巢狀結構的便利性是採用預先處理器最常見的原因之一。

@nest後,重複動作就會消失。幾乎所有預先支援處理器的巢狀結構功能都會內建在 CSS 中。

article {
  color: darkgray;
}

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

/* with @nest becomes */

article {
  color: darkgray;

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

與我建立巢狀結構的關係,最重要的是,除了在巢狀選取器中不會重複 article 以外,樣式結構定義仍保留在單一樣式區塊中。讀者不會從一個選取器及其樣式彈回至另一個具有樣式的選取器 (範例 1),讀者可以留在文章內容中,並看到文章本身所含的連結。關係和樣式意圖會組合在一起,因此 article 看起來就能擁有自己的樣式。

擁有權也可以視為集中式。比起尋找相關樣式的樣式表,所有內容都可以在結構定義中一起找到。這適用於子項關係,也適用於子項與父項關係。

假設在不同的父項情境下,想要自行調整元件子項,而不是擁有該樣式和變更子項的父項環境:

/* 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 可提升整體風格的組織、集中化與擁有權。元件可以分組並擁有自己的樣式,而不是分散在其他樣式區塊中。這些範例看似小,卻可能產生非常大的影響,既方便又易讀。

資源

設定範圍樣式真的很困難

瀏覽器支援

  • 118
  • 118
  • x
  • 17.4

@scope 之前,有許多策略是因為 CSS 階層結構、繼承,且預設限定在全域範圍。這些 CSS 功能在許多情況下都非常方便,但對於具有多種不同樣式的複雜網站和應用程式而言,瀑布的全域空間和性質可能會讓層疊的樣式感覺到外洩為止。

@scope 之後,樣式不僅能限定在特定情境 (例如類別),也可以說明樣式的結束位置,不會繼續串聯或沿用樣式。

在以下範例中,BEM 命名慣例可以還原為實際意圖。BEM 選取器嘗試將 header 元素的顏色範圍限定為採用命名慣例的 .card 容器。這要求標頭有此類別名稱,才能完成目標。使用 @scope 時,不需要命名慣例也能完成相同目標,而不必標記標頭元素:

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

資源

沒有透過 CSS 方式配置砌體版面配置

在搭配格線的 CSS 加工之前,JavaScript 是建立 Mastry 版面配置的最佳方式,因為任何含有欄或 Flbox 的 CSS 方法都無法準確呈現內容順序。

搭配格線繪製 CSS 之後,便不需要任何 JavaScript 程式庫,且內容順序會正確。

磚石版面配置的螢幕截圖,顯示數字沿著頂端移動,再往下移動。
Smashing Magazine 的圖片和示範內容
https://www.smashingmagazine.com/native-css-masonry-layout-css-grid/

上述示範是使用下列 CSS 完成:

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

瞭解雷達屬於缺少版面配置策略的情況,我們無從得知。此外,您也可以在 Firefox 中試用

資源

CSS 無法協助使用者減少數據用量

瀏覽器支援

  • x
  • x

資料來源

prefers-reduced-data 媒體查詢之前,JavaScript 和伺服器可能會根據使用者的作業系統或瀏覽器「數據節省模式」選項變更行為,但 CSS 無法這麼做。

執行 prefers-reduced-data 媒體查詢後,CSS 可以彙整使用者體驗強化措施,在儲存資料方面發揮作用。

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

上述 CSS 適用於這個媒體捲動元件,節省的費用可以大幅減少。視造訪可視區域的規模而定,載入網頁可省下的金額。當使用者與媒體捲動器互動時,系統會繼續儲存內容。所有圖片都具有 loading="lazy" 屬性,而且與 CSS 完全隱藏該元素後,就意味著圖片永遠不會發出網路要求。

電視節目輪轉介面介面的螢幕截圖,其中顯示許多縮圖和標題。

就我的測試而言,在中等大小的可視區域上,系統最初載入了 40 個要求和 700 KB 的資源。當使用者捲動媒體選取項目時,系統會載入更多要求和資源。使用 CSS 和縮減的資料媒體查詢時,系統會載入 10 個要求和 172 KB 的資源。這表示省下了 5 MB 的費用,而且使用者甚至沒有捲動任何媒體,因此不會提出額外要求。

電視節目輪轉介面介面的螢幕截圖,沒有任何縮圖和多個標題。

相較於節省數據用量,這種縮減資料體驗較具備其他優點。不僅能瀏覽更多標題,而且沒有令人分心的封面圖片可以分散注意力。許多使用者在瀏覽數據節省模式時,因為他們是按資料量計費,而看到 CSS 可以提供協助,這真的很棒。

資源

捲動貼齊功能受到限制

在這些捲動貼齊提案之前,編寫自己的 JavaScript 來管理輪轉介面、滑桿或圖片庫,可能會快速變得更加複雜,而且所有觀察器和狀態管理都包含在內。此外,如果不小心,自然捲動速度可能會透過指令碼正規化,導致使用者互動看起來有點不自然,可能又雜亂無章。

全新的 API

snapChanging()

瀏覽器釋出 Snap 子項後,就會觸發這個事件。這可讓 UI 反映出缺少貼齊子項,以及捲動工具的未驗證貼齊狀態 (因為現在使用中),並會到達新的位置。

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

瀏覽器貼齊新的子項,且捲動器恢復後後,就會觸發這個事件。如此一來,仰賴貼齊子項的任何 UI 就能更新並反映連線。

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

捲動頁面不一定會開始捲動。請考慮滑動可滑動的元件 (向左滑動或向右滑動會觸發不同事件),或是在頁面載入時最初隱藏搜尋列,直到捲動至頂端為止。這個 CSS 屬性可讓開發人員指定捲動器應從特定時間點開始。

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

.snap-scroll-y {
  scroll-start-y: var(--nav-height);
}
: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,以便您快速採用及測試這些功能。

資源

在已知狀態之間騎單車

toggle() 之前,只有瀏覽器內建的狀態可用於設定樣式和互動。舉例來說,核取方塊輸入內容含有 :checked,這是內部管理的瀏覽器狀態,可供 CSS 以視覺化方式變更元素。

toggle() 之後,您可以為任何元素建立自訂狀態,供 CSS 變更及用於樣式設定。可讓您進行群組、騎自行車、導向切換等等。

在以下範例中,完成清單項目加上刪除線的效果與完成項目相同,但沒有核取方塊元素:

<ul class='ingredients'>
   <li>1 banana
   <li>1 cup blueberries
  ...
</ul>

以及相關的 CSS toggle() 樣式:

li {
  toggle-root: check self;
}

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

如果您熟悉狀態機器,可能會注意到 toggle() 的跨界作業數量。這項功能可讓開發人員在 CSS 中建構更多狀態,希望能以更明確且更語意化的方式自動化調度管理互動和狀態。

資源

自訂選取元素

<selectmenu> 之前,CSS 無法自訂使用互動式多媒體 HTML 的 <option> 元素,也無法對選項清單顯示方式做出大幅調整。 這導致開發人員載入外部程式庫,重建了 <select> 的大部分功能,最終因此是一項工作。

<selectmenu> 之後,開發人員就能針對選項元素提供互動式多媒體 HTML,並根據需求設定樣式,同時仍符合無障礙需求並提供語意 HTML。

在以下範例中,我們從 <selectmenu> 說明頁面建立新的選取選單,並提供一些基本選項:

<selectmenu>
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</selectmenu>

CSS 可以指定元素的部分並設定樣式:

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

有紅色強調色的精選外觀選單。

您可以在啟用網頁實驗標記的情況下,在 Chromium 的 Canary 中試用 <selectmenu> 元素。我們將在 2023 年及之後推出可自訂的精選選單元素。

資源

將元素固定至其他元素

anchor() 之前,我們為開發人員提供位置絕對和相對位置策略,讓子項元素可在父項元素中移動。

anchor() 之後,無論元素是否為子項,開發人員都可以將元素放置在其他元素中。這個 API 也能讓開發人員指定要與哪個邊緣對齊,以及建立元素之間的位置關聯。

本文提供了一些絕佳範例和程式碼範例,歡迎多加參考。

資源