新一代網頁樣式設定

瞭解現代 CSS 有哪些令人期待的功能。

CSS 目前尚有很多令人興奮的事,但現今的瀏覽器已經支援許多這項功能!我們在 CDS 2019 舉辦的講座如下,其中說明我們應注意到的幾項新功能和即將推出的新功能。

本文著重介紹目前可使用的功能,因此請務必觀看相關內容,以深入探討 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 會設定為開始,該設定在每個圖片的左側設定貼齊點 (假設 direction 設為 ltr)。

下方是現場示範:

您也可以參考垂直捲動貼齊矩陣捲動貼齊的示範內容。

:focus-within

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

舉例來說,如果您的下拉式選單含有多個項目,則只有任一項目處於焦點時,選單才會顯示。否則鍵盤使用者的選單就會消失。

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

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

插圖:顯示焦點和聚焦在內的行為差異。

請嘗試在下方示範中使用 Tab 鍵瀏覽可聚焦元素。只要聚焦在選單項目上,選單就會持續顯示:

媒體查詢層級 5

新的媒體查詢方便我們根據使用者的裝置偏好設定,大幅調整應用程式的使用者體驗。基本上,瀏覽器可當做系統層級偏好設定的 Proxy,進而使用 prefers-* 媒體查詢群組在 CSS 中回應:

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

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

這些查詢能大幅提高無障礙體驗。之前我們無法判斷例如使用者是否已將 OS 設為高對比模式。如果您想為不影響品牌形象的網頁應用程式提供高對比模式,必須要求使用者從應用程式的使用者介面中選擇該模式。您現在可以使用 prefers-contrast 偵測作業系統的高對比設定。

這些媒體查詢帶來的影響之一,就是我們可以設計多種系統層級的使用者偏好組合,以配合各種使用者偏好和無障礙需求。如果使用者在光線昏暗的環境中想使用高對比深色模式,可以這麼做!

根據 Adam 的說法,「偏好減重動作」不會以「無動態」的形式導入。使用者表示自己偏好較少的動態效果,因為他們不希望加入任何動畫。他主張減少動作的效果並不在移動,以下範例顯示使用者偏好縮小動作時,使用交叉漸變動畫效果:

邏輯屬性

邏輯屬性可以解決因開發人員處理國際化問題,而日益普及的問題。marginpadding 等許多版面配置屬性,會假設讀取由上到下和從左到右的語言。

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

為使用不同書寫模式的多種語言設計網頁時,開發人員必須分別調整多個元素中的所有屬性,這樣很快就會成為維護能力的不足之處。

邏輯屬性可讓您維持不同翻譯和編寫模式的版面配置完整性。會依據內容的語意順序動態更新,而非空間排列方式。使用邏輯屬性時,每個元素都具有兩個維度:

  • 區塊維度與線條的文字流程垂直。(英文 block-sizeheight 相同)。
  • 「內嵌」維度與線條的文字流程平行。(英文 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 即將加入 Flexbox,讓目前的間距福利全都集於此:

  • 只有一個間距宣告,而不是多個空格。
  • 因此,您不需要為專案建立哪些子項元素應使用間距,因為所含元素原本擁有間距。
  • 程式碼比 lobotomized 貓 等較舊的策略容易理解。

以下影片將說明兩個元素使用單一 gap 屬性的好處,一個採用格線版面配置,另一個使用彈性版面配置:

目前,只有 FireFox 在 Flex 版面配置中支援 gap,但可以透過此示範來操作,以便瞭解其運作方式:

CSS 供應商 Houdini

Houdini 是瀏覽器轉譯引擎的一組低階 API,可以讓您告訴瀏覽器如何解讀自訂 CSS。也就是說,您可以使用 CSS 物件模型,透過 JavaScript 擴充 CSS。這麼做有幾個好處:

  • 能讓您進一步建立自訂 CSS 功能。
  • 更容易將算繪問題與應用程式邏輯區隔開來。
  • 比我們目前使用 JavaScript 的 CSS Polyfilling 更佳,因為瀏覽器不再需要剖析指令碼,也不必進行第二次轉譯循環;Houdini 程式碼會在第一個轉譯週期剖析。

插圖呈現 Houdini 與傳統 JavaScript polyfill 的運作方式。

Houdini 是數個 API 的綜合名稱,如要進一步瞭解 Pixel 7a 的設定和目前狀態,請參閱「尚未做好萬全準備嗎?」一文。我們在演講中探討了 Properties and Values API、Paint API 和 Animation Worklet,因為這些內容目前是最受支援的屬性。我們可以輕鬆針對這些令人興奮的 API 發表完整文章,但目前,我們會先查看 Google 的對話總覽,並提供一些有趣的示範,讓您大致瞭解這些 API 的功能。

溢位

還有更多我們想要探討的事情,但現在並沒有時間深入探討,所以我們很快就完成了這些功能。⚡如果你還未聽過這些功能,請務必觀看演講的最後一段部分

  • size:可讓您同時設定高度和寬度的屬性
  • aspect-ratio:這個屬性可為本身沒有顯示比例的元素設定顯示比例
  • min()max()clamp():這些函式可讓您設定任何 CSS 屬性的數字限制,而不只是寬度和高度
  • list-style-type 是現有屬性,但不久後將支援更多值,包括表情符號和可擴充向量圖形
  • display: outer innerdisplay 屬性即將接受兩個參數,可用來明確指定外部和內部版面配置,而不是使用 inline-flex 等複合關鍵字。
  • CSS 區域:可讓你填入指定的非矩形區域,
  • CSS 模組:JavaScript 能要求 CSS 模組,並傳回易於執行作業的豐富物件