2022 年 Google IO 所見,今日和明日的網頁樣式功能,還有其他功能。
2022 年是 CSS 最引以為傲的年份之一,同時涵蓋功能和可合作的瀏覽器功能,且共同目標是實作 14 項功能。
總覽
這篇文章是 2022 年 Google IO 大會上演講的文章版型。這不是每項功能的深入指南,而是介紹和簡要概述,以引起您的興趣,提供廣度而非深度。如果您對某個主題感興趣,請查看該主題結尾處的資源連結,進一步瞭解相關資訊。
目錄
請參閱下方清單,直接跳至您感興趣的主題:
瀏覽器相容性
之所以有這麼多 CSS 功能設定為合作發布,主要是因為 Interop 2022 的努力。在研究互通性工作之前,請務必瞭解 Compat 2021 的努力。
2021 年相容性
2021 年的目標是根據開發人員透過問卷調查提供的意見回饋,穩定現有功能、改善測試套件,並提高瀏覽器的五項功能通過分數:
- 「
sticky
」定位 aspect-ratio
大小- 「
flex
」版面配置 - 「
grid
」版面配置 - 「
transform
」定位和動畫
各項測試分數全面提升,展現更優異的穩定性和可靠性。在此向這些團隊致上誠摯的祝賀!
Interop 2022
今年,瀏覽器齊聚一堂,討論他們打算運用的功能和優先目標,並將各項工作統整在一起。他們打算為開發人員提供下列網頁功能:
@layer
- 色彩空間和函式
- 遏制
<dialog>
- 表單相容性
- 捲動
- 子格線
- 字體排版
- 可視區域單位
- 網路相容性
這份令人期待的雄心壯志清單,我迫不及待想看到它展開。
2022 年新鮮事
毫不意外,CSS 2022 的狀態受到 Interop 2022 工作影響甚鉅。
階層
在 @layer
之前,載入的樣式表格發現順序非常重要,因為最後載入的樣式可能會覆寫先前載入的樣式。這導致精心管理的輸入樣式表,開發人員必須先載入較不重要的樣式,再載入較重要的樣式。有許多完整的方法可協助開發人員管理這項重要性,例如 ITCSS。
有了 @layer
,輸入檔案就能預先定義圖層和圖層順序。接著,當樣式載入、載入或定義時,即可將其放置在圖層中,讓您保留樣式覆寫的重要性,但不必進行精細管理的載入協調作業。
這部影片說明如何定義層級串連,讓您在編寫和載入程序時享有更自由的編輯方式,同時仍可視需要維持層級串連。
Chrome 開發人員工具可協助您視覺化哪些樣式來自哪些圖層:
資源
子類別
在 subgrid
之前,另一個格線內的格線無法對齊其父項儲存格或格線線條。每個格線版面配置皆不相同。許多設計師會在整個設計上放置單一格線,並持續對齊其中的項目,但這在 CSS 中無法實現。
在 subgrid
之後,格線的子項可以採用父項的欄或列做為自己的欄或列,並將自己或子項對齊到這些項目!
在以下示範中,主體元素會建立包含三個資料欄的經典格線:中間資料欄名為 main
,左側欄和右側欄則命名其行
fullbleed
。然後,主體中的每個元素 <nav>
和 <main>
都會設定 grid-template-columns: subgrid
,採用主體中的已命名行。
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>
的子項可以使用 fullbleed
和 main
欄和行對齊或調整自身大小。
.main-content {
grid-column: main;
}
.fullbleed {
grid-column: fullbleed;
}
開發人員工具可協助您查看線條和子網格 (目前僅適用於 Firefox)。在下圖中,父項格線和子格線已重疊。這會讓版面配置看起來更像設計師的想法。
您可以在 devtools 的元素面板中,查看哪些元素是格線和子格線,這對於偵錯或驗證版面配置非常有幫助。
資源
容器查詢
在 @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
時,您可以做出許多令人興奮且有意義的設計決策。
資源
- 容器查詢規格
- 容器查詢說明
- MDN 上的容器查詢
- web.dev 推出全新回應式網頁
- Una 製作的日曆示範
- 超棒的容器查詢集合
- 我們如何在 web.dev 上建立 Designcember
- Ahmad Shaded:CSS 容器查詢功能簡介
accent-color
在 accent-color
之前,如果您想要建立與品牌相符的色彩表單,可能會使用到複雜的程式庫或 CSS 解決方案,這些解決方案會隨著時間推移而變得難以管理。雖然這些做法提供了所有選項,但希望能加入無障礙功能,但還是要選擇使用內建元件或自行採用,導致無法選擇使用。
在 accent-color
之後,一行 CSS 會為內建元件提供品牌顏色。除了色調之外,瀏覽器還會為元件的輔助部分選擇適當的對比色,並調整為系統色彩配置 (淺色或深色)。
/* tint everything */
:root {
accent-color: hotpink;
}
/* tint one element */
progress {
accent-color: indigo;
}
如要進一步瞭解 accent-color
,請查看我在 web.dev 上發布的文章,藉此探索這個實用 CSS 屬性的更多相關資訊。
資源
顏色等級 4 和 5
過去幾十年來,網路一直以 sRGB 為主,但在高解析度螢幕和預先配備 OLED 或 QLED 螢幕的行動裝置不斷增加的數位世界中,sRGB 已不足以應付。此外,我們也期待能提供可根據使用者偏好設定調整的動態頁面,而色彩管理已成為設計人員、設計系統和程式碼維護人員日益關注的議題。
不過,CSS 在 2022 年推出了許多新的顏色函式和空間: - 可支援顯示器的 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()
HWB 代表色調、白度和黑度。它是一種人性化的方式來表達顏色,因為它只是色調和白色或黑色的量,用於調整亮度或色調。混色白色或黑色的藝術家 可能會讓這種色彩語法更加出色。
使用這個色彩函式會產生 sRGB 色域的顏色,與 HSL 和 RGB 相同。就 2022 年的新功能而言,這項功能不會為您提供新的顏色,但可能會讓語法和心智模型的愛好者更輕鬆地完成某些工作。
資源
色域
色彩的呈現方式是透過色域完成。每個色彩空間都提供各種功能,以及使用顏色的權衡。有些人可能會將所有亮色系顏色放在一起;有些人則可能會先根據亮度排列。
2022 年推出的 CSS 提供 10 種新的色彩空間,每個空間各有獨特的功能,可協助設計人員和開發人員展示、挑選及混色。過去,sRGB 是唯一能使用顏色的選項,但現在 CSS 開創新潛力,也開創了全新的預設色域 LCH。
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);
}
以下是使用 color-mix()
的示範主題設定。請嘗試變更品牌顏色,並觀察主題更新情形:
2022 年,你可以在樣式表上運用各種顏色的空間盡情混色!
資源
color-contrast()
在 color-contrast()
之前,樣式表作者必須事先知道無障礙色彩。調色盤通常會在色塊上顯示黑色或白色的文字,向使用者指出色彩系統需要哪種文字顏色,才能與該色塊產生適當的對比效果。
在 color-contrast()
之後,樣式表作者可以將工作完全卸載至瀏覽器。您不僅可以利用瀏覽器自動挑選黑色或白色,還可以提供設計系統合適的顏色清單,並讓瀏覽器優先採用所需的對比度。
以下是 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 語言本身就內建適當的對比色彩,您就能更輕鬆地提供易讀、易懂的介面。
資源
相對色彩語法
在導入相對顏色語法之前,您必須將顏色通道分別放入自訂屬性,才能計算顏色並進行調整。由於色調、飽和度或亮度都可以透過 calc()
以簡單的方式調整,因此這項限制也讓 HSL 成為操控顏色的主要色彩函式。
在相對顏色語法之後,任何空間中的任何顏色都可以解構、修改,並以顏色形式傳回,所有這些操作都只需一行 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 可支援所有調色盤,每個調色盤都提供不同的基礎。還有一個好處,因為我用過 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);
}
希望您現在能夠根據色彩空間和不同色彩函式的優勢,瞭解顏色空間的強度和弱點,如何依不同目的使用。
資源
漸層色彩空間
在漸層色彩空間之前,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 點之間的直線,因此色彩空間的形狀會大幅改變路徑沿途的停靠站。
如需更深入的探索、範例和評論,請參閱這個 Twitter 主題串。
資源
inert
在 inert
推出前,引導使用者將焦點放在頁面或應用程式中需要立即注意的部分,是相當實用的做法。這項引導式焦點策略稱為焦點交易,因為開發人員會將焦點放在互動空間、監聽焦點變更事件,而且如果焦點離開互動空間,就會被強制返回。鍵盤或螢幕閱讀器的使用者將導回互動式空間,確認工作已完成,然後再繼續。
在 inert
之後,您可以凍結或保護網頁或應用程式的整個區塊,因此不需要進行擷取。當文件的這些部分處於靜態時,就無法進行點擊和焦點變更嘗試。您也可以將這視為守衛,而非陷阱,inert
不想讓您停留在某個地方,而是讓其他地方無法使用。
這方面的好例子就是 JavaScript 的 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 字型後,網頁的占用空間會變小,且可使用可縮放向量、可重新定位、具有漸層效果,以及支援混合模式的字型,這些字型可接受參數,以便針對個別用途自訂字型或配合品牌。
以下是 Chrome 開發人員網誌文章中的表情符號範例。也許您已經注意到,放大表情符號的字型大小後,會無法保持銳利清晰。這是圖片,而非向量藝術。在應用程式中使用表情符號時,系統通常會將其換成品質較高的素材資源。透過 COLRv1 字型,表情符號就具有向量和美觀的體驗:
圖示字型可透過此格式發揮驚人效果,提供自訂雙色調色盤等。載入 COLRv1 字型的方式與其他字型檔案相同:
@import url(https://fonts.googleapis.com/css2?family=Bungee+Spice);
您可以使用 @font-palette-values
自訂 COLRv1 字型,這是一種特殊的 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;
}
隨著可用的可變字型和彩色字型越來越多,網頁排版正朝著豐富的自訂和創意表達方向邁進。
資源
可視區域單元
在新的可視區域變化版本推出之前,網頁會提供實體單位,協助調整可視區域。其中共有高度、寬度、最小尺寸 (最小尺寸) 和最大邊 (vmax) 各有一個。這些做法在許多情況下都很實用,但行動瀏覽器帶來了複雜性。
在行動裝置上載入網頁時,會顯示含有網址的狀態列,且這個列會耗用部分可視區域空間。幾秒後,在經過一些互動後,狀態列可能會滑開,讓使用者享有更大的檢視區體驗。但當該列滑出時,可視區高度會變更,而任何 vh
單位都會隨著目標大小變更而移動及調整大小。幾年後,vh
單元必須特別決定要使用兩種可視區域大小中的哪一個,因為這會造成行動裝置上的視覺版面配置問題。我們判斷 vh
一律會代表最大的可視區域。
.original-viewport-units {
height: 100vh;
width: 100vw;
--size: 100vmin;
--size: 100vmax;
}
新的可視區域變化版本推出後,系統會提供小型、大型和動態可視區域單元,並在實體單元中加入邏輯等價。這項功能的用意是讓開發人員和設計人員能夠選擇在特定情境中使用的單位。狀態列消失時,版面配置稍微移位也許沒什麼大礙,因此您可以放心使用 dvh
(動態檢視區高度)。
以下是新檢視區變數提供的所有新檢視區單元選項完整清單:
.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()
在 :has()
之前,選取器的主體一律位於結尾。舉例來說,這個挑選器的主體是清單項目:ul > li
。偽選取器可以變更選取器,但不會變更主體:ul > li:hover
或 ul >
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>
)。在以下範例中,系統會選取含有圖說的圖片,然後選取該內容中的圖片。:has()
會用於指定圖片,而非圖形,因此不會變更主體:
figure:has(figcaption) img {...}
組合似乎無窮無盡。將 :has()
與數量查詢結合,並根據子項數量調整 CSS 格線版面配置。將 :has()
與互動式擬造類別狀態結合,並建立以新穎方式回應的應用程式。
您可以使用 @supports
和其 selector()
函式,輕鬆檢查瀏覽器是否支援語法,然後再使用該語法:
@supports (selector(:has(works))) {
/* safe to use :has() */
}
資源
2022 年及以後
在 2022 年推出所有精彩功能後,仍有許多事情難以完成。下一節將探討一些尚未解決的問題,以及我們正在積極開發的解決方案。這些解決方案屬於實驗性質,但可能會在瀏覽器中指定或透過標記提供。
下節的結論應該會讓您安心,因為我們列出的許多問題,都有許多公司在尋求解決方案,而非這些解決方案會在 2023 年推出。
鬆散型別的自訂屬性
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>
。這表示即使為其中一個自訂屬性提供無效值,陰影仍會繼續運作。而會改為回復為 0px
的 initial-value
。
動畫
除了類型安全性之外,它還能為動畫開啟許多大門。CSS 語法具備的彈性,使得無法為某些項目 (例如漸層) 製作動畫。@property
在這裡提供協助,因為以類型表示的 CSS 屬性可向瀏覽器告知開發人員在過於複雜的插補作業中所要表達的意圖。這項功能基本上會限制可能性範圍,讓瀏覽器能夠為先前無法處理的樣式方面製作動畫。
請參考以下示範範例,其中以放射漸層做為疊加部分,用來建立焦點焦點效果。按下 Alt/Option 鍵時,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-width
或 max-width
在媒體查詢範圍之前,CSS 媒體查詢會使用 min-width
和 max-width
來表達超過和低於條件。畫面可能會如下所示:
@media (min-width: 320px) {
…
}
在媒體查詢範圍後,相同的媒體查詢可能會如下所示:
@media (width >= 320px) {
…
}
同時使用 min-width
和 max-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 自訂屬性程式庫「Open Props」中,尋找我所使用的自訂媒體查詢完整清單。
資源
巢狀選取器真是太棒了
在 @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
可協助整體改善樣式組織、集中化和擁有權。元件可以將樣式分組並擁有自己的樣式,而不會將樣式分散在其他樣式區塊中。在這些範例中,這些變更看似微不足道,但對便利性和可讀性而言,影響可能非常大。
資源
設定範圍樣式真難
在 @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 是建立磚石版面配置的最佳方法,因為任何含資料欄或 Flexbox 的 CSS 方法都可能準確地代表內容順序。
使用 CSS 平鋪排版和格線後,就不需要 JavaScript 程式庫,且內容順序會正確顯示。
上述示範是透過下列 CSS 完成:
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
請放心,我們已將這項功能列為缺少的版面配置策略,而且您現在就能在 Firefox 中試用。
資源
CSS 無法協助使用者減少資料
在 prefers-reduced-data
媒體查詢之前,JavaScript 和伺服器可以根據使用者的作業系統或瀏覽器「資料儲存」選項變更行為,但 CSS 則無法。
在 prefers-reduced-data
媒體查詢之後,CSS 可加入使用者體驗改善作業,並在儲存資料方面發揮作用。
@media (prefers-reduced-data: reduce) {
picture, video {
display: none;
}
}
前一個 CSS 用於媒體捲動元件,可節省大量成本。視造訪可視區域的大小而定,載入網頁時節省的費用就越多。使用者與媒體捲軸互動時,系統會繼續儲存。圖片都具有 loading="lazy"
屬性,加上 CSS 會完全隱藏元素,因此系統不會發出圖片的網路要求。
在我的測試中,在中等大小的可視區域中,最初載入了 40 個要求和 700kb 的資源。當使用者捲動媒體選單時,系統會載入更多要求和資源。使用 CSS 和減少的資料媒體查詢,可以載入 10 個要求和 172 KB 的資源。這可節省半個位元組,而且使用者甚至沒有捲動任何媒體,因此不會產生其他要求。
除了節省資料外,這項功能還提供其他優點。這樣就能看到更多標題,而且沒有會分散注意力的封面圖片。許多使用者會在省用資料模式下瀏覽網頁,因為他們需要為每位元組資料付費。很高興看到 CSS 能夠在這方面提供協助。
資源
- prefers-reduced-data 規格
- prefers-reduced-data 在 Google 多媒體廣告聯播網上
- GUI 挑戰中的 prefers-reduced-data
- 《Smashing Magazine: Improving Core Web Vitals》(效能提升:網站體驗核心指標的效能),Smashing Magazine 案例研究
捲動貼齊功能過於受限
在這些捲動貼齊提案推出之前,如果要自行編寫 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 中的 <selectmenu>
元素。請留意 2023 年及以後可自訂的選單元素。
資源
將元素固定在另一個元素上
在 anchor()
推出之前,開發人員可使用絕對和相對定位策略,讓子項在父項元素中移動。
在 anchor()
之後,開發人員可以將元素放置到其他元素,無論是否為子項皆可。開發人員也可以使用這項功能指定要對齊哪個邊緣,以及其他用於建立元素之間位置關係的細節。
如想進一步瞭解,說明中提供了幾個實例和程式碼範例。