新一代網頁樣式設定

掌握最新 CSS 的部分精彩功能。

目前 CSS 有許多令人興奮的功能,而且許多功能已在目前的瀏覽器中支援!我們在 2019 年 CDS 的演講內容如下,其中介紹了幾項新功能和即將推出的功能,我們認為這些功能值得你多加留意。

這篇文章著重於介紹您現在就能使用的功能,因此請務必觀看這場演講,進一步瞭解 Houdini 等即將推出的功能。您也可以在 CSS@CDS 頁面中找到所有功能的示範。

目錄

捲動貼齊

捲動 Snap 可讓您在使用者垂直、水平或兩者皆垂直捲動內容時定義貼齊點。它提供內建的捲動慣性和減速功能,且支援觸控操作。

以下程式碼範例會在 <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 會設為 start,這會在每張相片的左側設定對齊點 (假設 direction 設為 ltr)。

以下是現場示範:

您也可以觀看垂直捲動貼齊矩陣捲動貼齊的示範。

:focus-within

:focus-within 解決長期以來的無障礙功能問題:在許多情況下,聚焦子項元素都應該影響父項元素的呈現方式,才能讓輔助技術的使用者存取 UI。

舉例來說,如果您有一個含有多個項目的下拉式選單,當任何項目獲得焦點時,選單應會持續顯示。否則,鍵盤使用者會看不到選單。

:focus-within 會在焦點位於指定元素的任何子項元素時,指示瀏覽器套用樣式。返回選單範例,只要在選單元素上設定 :focus-within,就能確保當選單項目成為焦點時,畫面上仍會持續顯示:

.menu:focus-within {
  display: block;
  opacity: 1;
  visibility: visible;
}

插圖:顯示焦點和內部焦點之間的行為差異。

請嘗試在下方示範中,透過 Tab 鍵瀏覽可聚焦的元素。您會發現,當您將焦點放在選單項目時,選單會持續顯示:

媒體查詢層級 5

新的媒體查詢提供強大的功能,可根據使用者的裝置偏好設定調整應用程式使用者體驗。基本上,瀏覽器會充當系統層級偏好的代理程式,我們可以使用 prefers-* 群組的媒體查詢在 CSS 中回應:

圖表顯示媒體查詢如何解讀系統層級的使用者偏好設定。

以下是我們認為開發人員最感興趣的新查詢:

這些查詢對於無障礙功能來說非常實用。舉例來說,我們先前無法得知使用者是否已將 OS 設為高對比模式。如果您想為網頁應用程式提供高對比模式,並維持品牌調性,就必須要求使用者在應用程式 UI 中選擇該模式。現在,您可以使用 prefers-contrast 從 OS 偵測高對比設定。

這些媒體查詢的一大作用,就是能配合各種使用者偏好和無障礙需求,設計多種系統層級使用者偏好設定組合。如果使用者想在光線昏暗的環境中使用高對比深色模式,你可以達成這項目標!

Adam 認為,「prefers reduced motion」不應實作為「no motion」。使用者表示他們偏好較少動態效果,並非不希望有任何動畫。他堅稱減少動態效果並非完全不使用動態效果。以下是使用者偏好減少動畫時,使用交叉淡出動畫的範例:

邏輯屬性

隨著越來越多開發人員著手處理國際化問題,邏輯屬性解決了這個問題。marginpadding 等許多版面配置屬性會假設使用由上至下及由左至右讀取的語言。

顯示傳統 CSS 版面配置屬性的圖表。

當開發人員為多種語言設計網頁時,由於每種語言的書寫模式不同,開發人員必須在多個元素中個別調整所有屬性,這很快就會變成難以維護的惡夢。

邏輯屬性可讓您在翻譯和書寫模式之間維持版面配置完整性。這些內容會根據內容的語意排序而非空間排列方式,進行動態更新。邏輯屬性可讓每個元素具有兩個維度:

  • 區塊維度與文字在行中的流動方向垂直。(英文 block-sizeheight 相同)。
  • inline 維度與文字在行內的流動方向平行。(英文 inline-sizewidth 相同)。

這些維度名稱適用於所有邏輯版面配置屬性。舉例來說,在英文中,block-starttop 相同,inline-endright 相同。

顯示新的 CSS 邏輯版面配置屬性的圖表。

使用邏輯屬性後,只要變更網頁的 writing-modedirection 屬性,即可自動更新其他語言的版面配置,而不需要更新個別元素的版面配置屬性。

您可以透過下方示範,瞭解邏輯屬性如何運作,方法是將 <body> 元素的 writing-mode 屬性設為不同的值:

position: sticky

含有 position: sticky 的元素會維持在區塊流程中,直到開始離開畫面為止。此時,該元素會停止與頁面其餘部分捲動,並停留在元素 top 值指定的位置。為該元素分配的空間會保留在流程中,並在使用者向上捲動時返回。

固定位置可讓您建立許多以往需要使用 JavaScript 的實用效果。為了展示一些可能性,我們製作了幾個示範。每個示範都使用大致相同的 CSS,只需稍微調整 HTML 標記即可建立各個效果。

固定堆疊

在本示範中,所有固定式元素都共用同一個容器。也就是說,當使用者向下捲動時,每個固定元素都會滑過先前的元素。固定式元素會使用相同的停滯位置。

頁緣固定投影片

在這個例子中,固定元素是表兄弟。(也就是說,父項是同層級元素)。當固定式元素到達容器的底部邊界時,就會與容器一起向上移動,這樣會讓較不固定的元素再次向上提升。換句話說,它們看起來似乎正在競爭停滯不前。

Sticky Desperado

就像黏滑幻燈片一樣,這個示範中的黏滑元素也是類似的概念。不過,這些程式碼也加在採用兩欄格狀版面配置的容器中。

backdrop-filter

backdrop-filter 屬性可讓您將圖形效果套用至元素「後方」的區域,而非元素本身。這項功能可讓您只需使用一行 CSS 程式碼,就能實現先前只能透過複雜的 CSS 和 JavaScript 駭客攻擊才能達成的許多酷炫效果。

舉例來說,這個示範使用 backdrop-filter 實現 OS 風格的模糊效果:

我們已經發布有關 backdrop-filter 的優質文章,請前往該文章瞭解更多資訊。

:is()

雖然 :is() 擬物類別已推出超過十年,但我們認為這項功能的使用率仍不如預期。這個函式會將以半形逗號分隔的選取器清單做為引數,並比對清單中的任何選取器。這種彈性讓它非常實用,而且可以大幅減少您提供的 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 時,您不必擔心子元素的邊界會在包含元素的邊緣周圍產生不必要的空白:

插圖:說明 gap 屬性如何避免在容器元素邊緣周圍產生不必要的間距。

更棒的是,gap 即將採用 Flexbox,提供與格狀空間相同的所有間距:

  • 系統只有一個間距宣告,而非多個間距。
  • 您不需要為專案建立慣例,說明哪些子元素應擁有間距,因為包含元素會擁有間距。
  • 相較於腦葉切除的貓頭鷹等舊策略,這段程式碼更容易理解。

以下影片說明在兩個元素 (一個使用格線版面配置,另一個使用 Flex 版面配置) 中使用單一 gap 屬性的優點:

目前只有 Firefox 支援 Flex 版面配置中的 gap,但您可以透過以下示範瞭解其運作方式:

CSS Houdini

Houdini 是瀏覽器算繪引擎的一組低階 API,可讓您告知瀏覽器如何解讀自訂 CSS。換句話說,您可以透過此 API 存取 CSS 物件模型,進而透過 JavaScript 擴充 CSS。這麼做有幾個好處:

  • 讓您以更強大的功能建立自訂 CSS 功能。
  • 這麼做可更輕鬆地將轉譯問題與應用程式邏輯分開。
  • 效能優於我們目前採用 JavaScript 的 CSS 聚合功能,因為瀏覽器不必再剖析指令碼,並執行第二次的轉譯週期;Houdini 程式碼是在第一個轉譯週期中剖析。

顯示 Houdini 與傳統 JavaScript polyfill 比較運作方式的插圖。

Houdini 是多個 API的總稱。如要進一步瞭解這些功能和目前狀態,請參閱「Houdini 是否已就緒?」在本次演講中,我們會介紹 Properties and Values API、Paint API 和 Animation Worklet,因為這些是目前最受支援的 API。我們可以輕鬆將一篇完整的文章公布到各個令人期待的 API 上,但目前請先前往我們的講座網站查看總覽內容,並瞭解一些有趣的實際示範,幫助您瞭解 API 的用途。

溢位

我們還有幾項想討論的內容,但沒有時間深入說明,因此我們會快速瀏覽這些內容。⚡如果您還不熟悉其中某些功能,請務必觀看演講的最後部分

  • size:可同時設定高度和寬度的屬性
  • aspect-ratio:為不具備顯示比例的元素設定顯示比例的屬性
  • min()max()clamp():這些函式可讓您為任何 CSS 屬性 (而非僅限於寬度和高度) 設定數值限制
  • list-style-type 是現有屬性,但很快就會支援更多值,包括表情符號和 SVG
  • display: outer innerdisplay 屬性很快就會接受兩個參數,讓您明確指定外部和內部版面配置,而非使用 inline-flex 等複合關鍵字。
  • CSS 區域:可讓您填入指定的非矩形區域,讓內容可流入和流出
  • CSS 模組:JavaScript 可要求 CSS 模組,並取得可輕鬆執行作業的豐富物件