本文的主要目的是與你分享我對 CSS Houdini 這個新增功能的瞭解,並告訴你為什麼它如此重要。
你可以在網上找到幾篇不錯的講解 Houdini 的文章,但對於那些想要在深入瞭解細節之前先大致瞭解一下的人來說,這篇文章將是一個很好的開始。
已經有人預測,Houdini“將改變 CSS,而不是 flex 和 grid 結合在一起”,所以廢話不多說,讓我們開始正文吧!
簡單地說,Houdini 是一組 API,它暴露了 CSS 的一部分,使工程師能夠用 JavaScript 編寫程式碼,然後瀏覽器將其解析為 CSS。
這是透過使用名為 worklet 的介面擴充套件 CSS 程式碼來完成的,這些介面是在呈現頁面時執行的指令碼。
藉助 worklet,我們可以直接更改 CSS 變數。換句話說,這些 API 允許工程師透過直接連線到 CSS 渲染引擎來操作樣式、動畫、佈局並新增高階自定義屬性、型別檢查和預設值。
但是,首先,直接修改 CSS 而不是像我們可能習慣的那樣使用 JavaScript 在其之上新增功能有什麼好處?最短的答案是效能。
瀏覽器建立兩個物件模型:HTML 標記轉換為文件物件模型 (DOM) 和 CSS 標記轉換為 CSS 物件模型 (CSSOM),它們是兩個獨立的物件。
JavaScript 操作 DOM,這意味著為了對 DOM 或樣式應用任何“更正”,頁面需要完全載入。當使用 JavaScript 操作 DOM 時,頁面會再次重新呈現。
如果我們能夠直接修改 CSS,就不需要重新渲染 DOM。然而,使用 Houdini API 方法,我們告訴瀏覽器如何在渲染過程中應用 CSS,從而避免第二次重新渲染。
另一個重要優勢是模組化。Houdini 幫助我們編寫程式碼片段並將它們作為可共享模組匯入,這在概念上更類似於 JavaScript 而不是 CSS。假設我們想為一個按鈕元件建立特定的樣式,然後我們想在專案的不同部分使用它。
現在我們很可能會透過複製貼上 CSS 來複制程式碼。然而,使用 Houdini,我們可以簡單地編寫一個定義了所有按鈕樣式的工作集,並將它們匯入到需要它們的地方,甚至在不同的專案中共享它們。
現在讓我們快速瀏覽一下 API 及其提供的功能。Houdini API 可以分為兩類:允許我們修改可見樣式、佈局等的 API,以及幫助我們定義特定屬性型別並新增自定義屬性和值的 API。
繪畫 API。允許我們在瀏覽器的繪製渲染階段修改視覺屬性,例如顏色、背景邊框等;
**佈局 API。**讓我們在瀏覽器的佈局渲染階段修改元素的大小和位置(藉助 CSSdisplay
屬性);
**動畫 API。**允許在瀏覽器的渲染階段為元素設定動畫。它還使我們能夠監聽事件,例如滾動、懸停、單擊等,並讓我們在自己的單獨執行緒上執行動畫,從而提高效能。
**CSS 型別化物件模型。**透過將 CSS 值公開為型別化 JavaScript 物件來為 CSS 值新增更多語義含義。
CSS 屬性和值 API。允許透過新增型別、初始值和定義繼承來擴充套件 CSS 變數。
現在讓我們看一下幾個 API,以瞭解語法以及我們可以用它們做什麼。
這是一個使用了 CSS 屬性和值 API 的簡單示例,我們可以為自定義屬性提供一個結構。
假設我們有一個 CSS 自定義屬性(自定義屬性以“—”為字首)
--myFavoriteColor: #0000ff;
然後我們可以將此屬性用作變數
.div {
background-color: var(--myFavoriteColor);
}
但是,如果我們不小心將 --myFavoriteColor
更改為 12px
,那麼會發生什麼呢?
沒有任何警告提示我們 background-color
現在有一個不正確的型別,並且在我們不知道的情況下,這個錯誤會被簡單地忽略。
然而,Houdini 允許我們定義這個變數的型別:
@property --myFavoriteColor {
syntax: ‘<color>’;
inherits: false;
initial-value: #0000ff;
}
現在瀏覽器知道這個特定屬性應該是什麼,應該如何解析,是否應該繼承它的父值以及它的初始值應該是什麼,這也是在它被錯誤地覆蓋或出現錯誤時採用的後備方案。
讓我們看另一個簡單的示例,這次是型別化物件模型 (Typed OM),它擴充套件了 CSS 物件模型並將 CSS 值作為型別化 JavaScript 物件公開。這使得 CSS 看起來更像我們在 JavaScript 中習慣看到的那樣,並幫助我們更輕鬆、更直觀地訪問 CSS 值。
我們可以使用兩種主要方法:attributeStyleMap
,它允許我們獲取和設定內聯樣式;computedStyleMap
,我們可以用它獲取計算和型別化元素的樣式。
現在可以使用attributeStyleMap
方法設定此值:
document.querySelector('element').attributeStyleMap().set('font-size', CSS.percent(5);
並以相同的方式訪問:
document.querySelector('element').attributeStyleMap().get('font-size'); // { value: 5, unit: percent}
clear
, delete
,has
和append
方法也可用。
同樣,computedStyleMap
在完成所有計算之後(例如,將百分比值轉換為畫素)會獲取計算樣式。
毋庸置疑,最大的樂趣其實在於那些高階的 API,例如 Paint、Layout 和 Animation。但是,在如此短的文章中,它們的解釋和展示也更加複雜。
此外,目前並非所有瀏覽器都支援它們。但是,如果你對這些 API 感興趣,我強烈建議你檢視這些 API 的文件和示例。
那麼,如果 Houdini 真的會為 CSS 帶來重大的變化,為什麼大家還沒有談論它呢?好吧,因為它仍處於開發階段。
並非所有 Houdini API 都已實現,並且它們的支援因瀏覽器而異。
例如,Mozilla Firefox 尚不支援任何功能。在這個網站上,你可以檢視正在開發的 Houdini 功能的概述以及哪些功能可以安全使用。
此外,可以在網上找到的程式碼示例也可能會發生變化。但是,即使我們還不能開始在生產中使用這些 API,也值得了解和注意這個東西。