CSS Houdini 實用概述

已發表: 2022-03-10
快速總結 ↬ Houdini 是瀏覽器 API 集合的總稱,旨在為 Web 開發過程和總體 CSS 標準的開髮帶來重大改進。 前端開發人員將能夠使用 JavaScript 使用新功能擴展 CSS,連接到 CSS 渲染引擎並告訴瀏覽器如何在渲染過程中應用 CSS。 Houdini 的瀏覽器支持正在改進,一些 API 現在可以使用,所以現在是熟悉它們並進行試驗的好時機。 我們將看看 Houdini 的每個部分,它當前的瀏覽器支持,並看看它們現在如何使用漸進增強來使用。

新的 CSS 功能或改進需要很長時間才能從最初的草案發展到開發人員可以使用的完全支持且穩定的 CSS 功能。 基於 JavaScript 的 polyfill 可以用來替代缺乏瀏覽器支持的情況,以便在正式​​實現之前使用新的 CSS 功能。 但在大多數情況下,它們是有缺陷的。 例如,scrollsnap-polyfill 是幾個可用於修復瀏覽器支持 CSS Scroll Snap 規範不一致的 polyfill 之一。 但即使是那個解決方案也有一些限制、錯誤和不一致。

使用 polyfill 的潛在缺點是它們會對性能產生負面影響並且難以正確實施。 這個缺點與瀏覽器的 DOM 和 CSSOM 有關。 瀏覽器從 HTML 標記創建DOM(文檔對像模型) ,類似地,它從 CSS 標記創建CSSOM(CSS 對像模型) 。 這兩個對象樹相互獨立。 JavaScript 在 DOM 上工作,對 CSSOM 的訪問非常有限。

JavaScript Polyfill 解決方案僅在初始渲染週期完成後運行,即當 DOM 和 CSSOM 都已創建且文檔已完成加載時。 在 Polyfill 對 DOM 中的樣式進行更改(通過內聯樣式)後,它會導致渲染過程再次運行並且整個頁面重新渲染。 如果它們依賴於requestAnimationFrame方法或依賴於滾動事件等用戶交互,負面的性能影響會更加明顯。

Web 開發的另一個障礙是CSS 標準施加的各種限制。 例如,只有有限數量的 CSS 屬性可以進行原生動畫處理。 CSS 知道如何對顏色進行原生動畫處理,但不知道如何對漸變進行動畫處理。 儘管存在技術限制,但始終需要通過突破界限來創新和創造令人印象深刻的網絡體驗。 這就是為什麼開發人員經常傾向於使用不太理想的解決方法或 JavaScript 來實現 CSS 目前不支持的更高級的樣式和效果,例如砌體佈局、高級 3D 效果、高級動畫、流體排版、動畫漸變、樣式select元素等

CSS 規範似乎不可能跟上行業的各種功能需求,例如對動畫的更多控制、改進的文本截斷、更好的inputselect元素樣式選項、更多display選項、更多filter選項等。

可能的解決方案是什麼? 為開發人員提供一種使用各種 API 擴展 CSS 的本地方式。 在本文中,我們將看看前端開發人員如何使用 Houdini API、JavaScript 和 CSS 來做到這一點。 在每一節中,我們將分別檢查每個 API,檢查其瀏覽器支持和當前規範狀態,並了解如何使用漸進式增強來實現它們。

跳躍後更多! 繼續往下看↓

什麼是胡迪尼?

Houdini 是瀏覽器 API 集合的總稱,旨在為 Web 開發過程和總體 CSS 標準的開髮帶來重大改進。 開發人員將能夠使用 JavaScript 擴展 CSS 的新功能,連接到 CSS 渲染引擎,並告訴瀏覽器如何在渲染過程中應用 CSS。 與使用常規 polyfill 相比,這將顯著提高性能和穩定性。

Houdini 規範由兩個 API 組組成——高級 API低級 API

高級 API與瀏覽器的渲染過程(樣式 → 佈局 → 繪製 → 合成)密切相關。 這包括:

  • 繪畫 API
    確定視覺屬性(顏色、背景、邊框等)的瀏覽器繪製渲染步驟的擴展點。
  • 佈局 API
    確定元素尺寸、位置和對齊方式的瀏覽器佈局渲染步驟的擴展點。
  • 動畫 API
    瀏覽器複合渲染步驟的擴展點,其中圖層被繪製到屏幕上並設置動畫。

低級 API構成了高級 API 的基礎。 這包括:

  • 類型化對像模型 API
  • 自定義屬性和值 API
  • 字體指標 API
  • 工作集

一些 Houdini API 已經可以在一些瀏覽器中使用,而其他 API 在它們準備好發佈時也會效仿。

CSS 的未來

與迄今為止引入的常規 CSS 功能規範不同,Houdini 通過允許開發人員以更原生的方式擴展 CSS 脫穎而出。 這是否意味著 CSS 規範將停止發展,並且不會發布新的官方 CSS 功能實現? 好吧,事實並非如此。 Houdini 的目標是通過允許開發人員創建易於標準化的工作原型來幫助 CSS 功能開發過程。

此外,開發人員將能夠更輕鬆地共享開源 CSS Worklets,並且減少對特定於瀏覽器的錯誤修復的需求。

類型化對像模型 API

在引入 Houdini 之前,JavaScript 與 CSS 交互的唯一方法是解析表示為字符串值的 CSS 並修改它們。 由於需要來回更改值類型以及在分配新值時需要手動附加值單元,手動解析和覆蓋樣式可能很困難且容易出錯。

 selectedElement.style.fontSize = newFontSize + "px"; // newFontSize = 20 console.log(selectedElement.style.fontSize); // "20px"

類型化對像模型 (Typed OM) API 通過將 CSS 值公開為類型化 JavaScript 對象,為 CSS 值添加了更多語義含義。 它顯著改進了相關代碼,使其更具性能、穩定性和可維護性。 CSS 值由CSSUnitValue接口表示,該接口由一個值和一個單元屬性組成。

 { value: 20, unit: "px" }

這個新接口可以與以下新屬性一起使用:

  • computedStyleMap() :用於解析計算(非內聯)樣式。 這是在解析或使用其他方法之前需要調用的選定元素的方法。
  • attributeStyleMap :用於解析和修改內聯樣式。 這是在選定元素上可用的屬性。
 // Get computed styles from stylesheet (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Set inline styles selectedElement.attributeStyleMap.set("font-size", CSS.em(2)); // Sets inline style selectedElement.attributeStyleMap.set("color", "blue"); // Sets inline style // Computed style remains the same (initial value) selectedElement.computedStyleMap().get("font-size"); // { value: 20, unit: "px"} // Get new inline style selectedElement.attributeStyleMap.get("font-size"); // { value: 2, unit: "em"}

請注意在設置新數值時如何使用特定的 CSS 類型。 通過使用這種語法,可以避免許多潛在的與類型相關的問題,並且生成的代碼更可靠且沒有錯誤。

getset方法只是 Typed OM API 定義的所有可用方法的一小部分。 其中一些包括:

  • clear : 移除所有內聯樣式
  • delete :從內聯樣式中刪除指定的 CSS 屬性及其值
  • has :如果設置了指定的 CSS 屬性,則返回布爾值
  • append :向支持多個值的屬性添加附加值
  • 等等。

特徵檢測

var selectedElement = document.getElementById("example"); if(selectedElement.attributeStyleMap) { /* ... */ } if(selectedElement.computedStyleMap) { /* ... */ }

W3C 規範狀態

  • 工作草案:發布供社區審查

瀏覽器支持

谷歌瀏覽器微軟邊緣歌劇瀏覽器火狐蘋果瀏覽器
支持的支持的支持的不支持部分支持 (*)

*支持“實驗性 Web 平台功能”或啟用其他功能標誌。

數據來源:Houdini 準備好了嗎?

自定義屬性和值 API

CSS 屬性和值API 允許開發人員通過添加類型、初始值和定義繼承來擴展 CSS 變量。 開發人員可以通過使用registerProperty方法註冊 CSS 自定義屬性來定義 CSS 自定義屬性,該方法告訴瀏覽器如何轉換它並在出現錯誤時處理回退。

 CSS.registerProperty({ name: "--colorPrimary", syntax: "<color>", inherits: false, initialValue: "blue", });

此方法接受輸入參數,該參數是具有以下屬性的對象:

  • name :自定義屬性的名稱
  • syntax :告訴瀏覽器如何解析自定義屬性。 這些是預定義的值,例如<color><integer><number><length><percentage>等。
  • inherits :告訴瀏覽器自定義屬性是否繼承其父級的值。
  • initialValue :告訴在它被覆蓋之前使用的初始值,這在發生錯誤時用作後備。

在以下示例中,將設置<color>類型自定義屬性。 此自定義屬性將用於漸變過渡。 您可能會認為當前的 CSS 不支持背景漸變的過渡,您是對的。 注意自定義屬性本身是如何在transition中使用的,而不是用於常規background-color轉換的background屬性。

 .gradientBox { background: linear-gradient(45deg, rgba(255,255,255,1) 0%, var(--colorPrimary) 60%); transition: --colorPrimary 0.5s ease; /* ... */ } .gradientBox:hover { --colorPrimary: red /* ... */ }

瀏覽器不知道如何處理漸變過渡,但它知道如何處理顏色過渡,因為自定義屬性被指定為<color>類型。 在支持 Houdini 的瀏覽器上,當元素懸停時會發生漸變過渡。 漸變位置百分比也可以用 CSS 自定義屬性(註冊為<percentage>類型)替換,並以與示例中相同的方式添加到過渡中。

如果registerProperty被移除,並且在:root選擇器中註冊了常規​​ CSS 自定義屬性,則漸變過渡將不起作用。 需要使用registerProperty以便瀏覽器知道它應該將其視為顏色。

在此 API 的未來實現中,可以直接在 CSS 中註冊自定義屬性。

 @property --colorPrimary { syntax: "<color>"; inherits: false; initial-value: blue; }

例子

這個簡單的示例分別使用註冊的 CSS 自定義屬性為顏色和位置展示了懸停事件上的漸變顏色和位置轉換。 示例存儲庫中提供了完整的源代碼。

使用自定義屬性和值 API 的動畫漸變顏色和位置。 為 CSS 過渡屬性中的效果添加的每個屬性的延遲。 (大預覽)

特徵檢測

if (CSS.registerProperty) { /* ... */ }

W3C 規範狀態

  • 工作草案:發布供社區審核

瀏覽器支持

谷歌瀏覽器微軟邊緣歌劇瀏覽器火狐蘋果瀏覽器
支持的支持的支持的不支持不支持

數據來源:Houdini 準備好了嗎?

字體指標 API

Font Metrics API 仍處於非常早期的開發階段,因此其規範可能會在未來發生變化。 在其當前草案中, Font Metrics API將提供測量屏幕上呈現的文本元素尺寸的方法,以便開發人員能夠影響文本元素在屏幕上的呈現方式。 這些值很難或不可能用當前的特性來衡量,因此這個 API 將允許開發人員更輕鬆地創建與文本和字體相關的 CSS 特性。 多行動態文本截斷是這些功能之一的示例。

W3C 規範狀態

  • 創意合集:暫未提交規範草案

瀏覽器支持

谷歌瀏覽器微軟邊緣歌劇瀏覽器火狐蘋果瀏覽器
不支持不支持不支持不支持不支持

數據來源:Houdini 準備好了嗎?

工作集

在轉向其他 API 之前,解釋一下 Worklets 概念很重要。 Worklet是在渲染期間運行的腳本,獨立於主要的 JavaScript 環境。 它們是渲染引擎的擴展點。 它們專為並行性(具有 2 個或更多實例)和線程無關而設計,減少了對全局範圍的訪問,並在需要時由渲染引擎調用。 Worklet 只能在 HTTPS(在生產環境中)或 localhost(用於開發目的)上運行。

Houdini 引入了以下 Worklets 來擴展瀏覽器渲染引擎:

  • 繪製工作集 - 繪製 API
  • 動畫工作集 - 動畫 API
  • 佈局工作集 - 佈局 API

繪畫 API

Paint API 允許開發人員使用 JavaScript 函數直接繪製元素的背景、邊框或使用 2D 渲染上下文的內容,這是 HTML5 Canvas API 的子集。 Paint API 使用 Paint Worklet 來繪製動態響應 CSS 變化的圖像(例如 CSS 變量的變化)。 任何熟悉 Canvas API 的人都會對 Houdini 的 Paint API 感到賓至如歸。

定義 Paint Worklet 需要幾個步驟:

  1. 使用registerPaint函數編寫和註冊一個 Paint Worklet
  2. 使用CSS.paintWorklet.addModule函數在 HTML 文件或主 JavaScript 文件中調用 Worklet
  3. 在 CSS 中使用帶有 Worklet 名稱和可選輸入參數的paint()函數。

讓我們看一下用於註冊 Paint Worklet 並定義其功能的registerPaint函數。

 registerPaint("paintWorketExample", class { static get inputProperties() { return ["--myVariable"]; } static get inputArguments() { return ["<color>"]; } static get contextOptions() { return {alpha: true}; } paint(ctx, size, properties, args) { /* ... */ } });

registerPaint函數由幾個部分組成:

  • inputProperties
    Worklet 將跟踪的一組 CSS 自定義屬性。 該數組表示繪製工作集的依賴關係。
  • inputArguments
    可以從 CSS 內部的paint函數傳遞的輸入參數數組。
  • contextOptions :允許或禁止顏色的不透明度。 如果設置為false ,所有顏色都將以完全不透明度顯示。
  • paint :提供以下參數的主函數:
    • ctx : 2D 繪圖上下文,幾乎與 Canvas API 的 2D 繪圖上下文相同。
    • size :包含元素寬度和高度的對象。 值由佈局呈現過程確定。 畫布大小與元素的實際大小相同。
    • properties : inputProperties中定義的輸入變量
    • args :在 CSS 中的paint函數中傳遞的輸入參數數組

註冊 Worklet 後,只需提供文件路徑即可在 HTML 文件中調用它。

 CSS.paintWorklet.addModule("path/to/worklet/file.js");

任何 Worklet 也可以從外部 URL(例如,從內容交付網絡)添加,這使得它們成為模塊化和可重用的。

 CSS.paintWorklet.addModule("https://url/to/worklet/file.js");

調用 Worklet 後,可以使用paint函數在 CSS 中使用它。 此函數接受 Worklet 的註冊名稱作為第一個輸入參數,其後的每個輸入參數都是一個自定義參數,可以傳遞給 Worklet(在 Worklet 的inputArguments中定義)。 從那時起,瀏覽器確定何時調用 Worklet 以及響應哪些用戶操作和 CSS 自定義屬性值更改。

 .exampleElement { /* paintWorkletExample - name of the worklet blue - argument passed to a Worklet */ background-image: paint(paintWorketExample, blue); }

例子

以下示例展示了 Paint API 和一般 Worklet 的可重用性和模塊化。 它直接使用 Google Chrome Labs 存儲庫中的漣漪 Worklet,並在具有不同樣式的不同元素上運行。 示例存儲庫中提供了完整的源代碼。

波紋效果示例(使用 Google Chrome Labs 的 Ripple Worklet)(大預覽)

特徵檢測

if ("paintWorklet" in CSS) { /* ... */ } @supports(background:paint(paintWorketExample)){ /* ... */ }

W3C 規範狀態

  • 候選推薦:穩定的工作草案準備實施

瀏覽器支持

谷歌瀏覽器微軟邊緣歌劇瀏覽器火狐蘋果瀏覽器
支持的支持的支持的不支持不支持

數據來源:Houdini 準備好了嗎?

動畫 API

Animation API 擴展了 Web 動畫,提供了監聽各種事件(滾動、懸停、單擊等)的選項,並通過使用 Animation Worklet 在其自己的專用線程上運行動畫來提高性能。 它允許用戶操作來控制以高性能、非阻塞方式運行的動畫流。

與任何 Worklet 一樣,Animation Worklet 需要先註冊。

 registerAnimator("animationWorkletExample", class { constructor(options) { /* ... */ } animate(currentTime, effect) { /* ... */ } });

這個類包含兩個函數:

  • constructor :在創建新實例時調用。 用於一般設置。
  • animate :包含動畫邏輯的主函數。 提供以下輸入參數:
    • currentTime : 定義時間線中的當前時間值
    • effect : 此動畫使用的一系列效果

註冊 Animation Worklet 後,需要將其包含在主 JavaScript 文件中,需要定義動畫(元素、關鍵幀、選項)並使用選定的時間軸實例化動畫。 時間軸概念和網絡動畫基礎知識將在下一節中解釋。

 /* Include Animation Worklet */ await CSS.animationWorklet.addModule("path/to/worklet/file.js");; /* Select element that's going to be animated */ const elementExample = document.getElementById("elementExample"); /* Define animation (effect) */ const effectExample = new KeyframeEffect( elementExample, /* Selected element that's going to be animated */ [ /* ... */ ], /* Animation keyframes */ { /* ... */ }, /* Animation options - duration, delay, iterations, etc. */ ); /* Create new WorkletAnimation instance and run it */ new WorkletAnimation( "animationWorkletExample" /* Worklet name */ effectExample, /* Animation (effect) timeline */ document.timeline, /* Input timeline */ {}, /* Options passed to constructor */ ).play(); /* Play animation */

時間線映射

Web 動畫基於時間線和當前時間到效果本地時間的時間線的映射。 例如,讓我們看一個具有 3 個關鍵幀(開始、中間、最後一個)的重複線性動畫,該動畫在頁面加載(延遲)後 1 秒運行,持續時間為 4 秒。

示例中的效果時間線如下所示(持續時間為 4 秒,無延遲):

效果時間線(4秒持續時間) 關鍵幀
0ms 第一個關鍵幀 - 動畫開始
2000毫秒中間關鍵幀 - 動畫正在進行中
4000毫秒最後一個關鍵幀 - 動畫結束或重置到第一個關鍵幀

為了更好地理解effect.localTime ,通過將其值設置為 3000 毫秒(考慮到 1000 毫秒延遲),生成的動畫將被鎖定到效果時間軸中的中間關鍵幀(1000 毫秒延遲 + 中間關鍵幀 2000 毫秒)。 將值設置為 7000 毫秒和 11000 毫秒會產生相同的效果,因為動畫以 4000 毫秒的間隔(動畫持續時間)重複。

 animate(currentTime, effect) { effect.localTime = 3000; // 1000ms delay + 2000ms middle keyframe }

當具有恆定的effect.localTime值時不會發生動畫,因為動畫被鎖定在特定的關鍵幀中。 為了正確地為元素設置動畫,它的effect.localTime需要是動態的。 該值必須是一個取決於currentTime輸入參數或其他變量的函數。

以下代碼顯示了時間線的 1:1(線性函數)映射以影響本地時間的功能表示。

 animate(currentTime, effect) { effect.localTime = currentTime; // y = x linear function }
時間線 ( document.timeline ) 映射效果當地時間關鍵幀
startTime + 0ms(經過的時間) startTime + 0 毫秒第一的
startTime時間 + 1000 毫秒(經過的時間) startTime時間 + 1000 毫秒(延遲) + 0 毫秒第一的
startTime + 3000ms(經過的時間) startTime時間 + 1000 毫秒(延遲) + 2000 毫秒中間
startTime時間 + 5000 毫秒(經過的時間) startTime時間 + 1000 毫秒(延遲) + 4000 毫秒最後/第一個
startTime + 7000ms(經過的時間) startTime時間 + 1000 毫秒(延遲) + 6000 毫秒中間
startTime + 9000ms(經過的時間) startTime時間 + 1000 毫秒(延遲) + 8000 毫秒最後/第一個

時間線不限於與效果本地時間的 1:1 映射。 Animation API 允許開發人員通過使用標準 JavaScript 函數來操作animate函數中的時間軸映射來創建複雜的時間軸。 動畫也不必在每次迭代中表現相同(如果重複動畫)。

動畫不必依賴於文檔的時間線,它只從加載的那一刻開始計算毫秒數。 通過使用ScrollTimeline對象,可以將滾動事件等用戶操作用作動畫的時間線。 例如,動畫可以在用戶滾​​動到 200 像素時開始,並且可以在用戶在屏幕上滾動到 800 像素時結束。

 const scrollTimelineExample = new ScrollTimeline({ scrollSource: scrollElement, /* DOM element whose scrolling action is being tracked */ orientation: "vertical", /* Scroll direction */ startScrollOffset: "200px", /* Beginning of the scroll timeline */ endScrollOffset: "800px", /* Ending of the scroll timeline */ timeRange: 1200, /* Time duration to be mapped to scroll values*/ fill: "forwards" /* Animation fill mode */ }); ...

動畫將自動適應用戶滾動速度並保持流暢和響應。 由於 Animation Worklet 運行在主線程之外並連接到瀏覽器的渲染引擎,因此依賴於用戶滾動的動畫可以流暢地運行並且非常高效。

例子

以下示例展示瞭如何實現非線性時間線。 它使用修改後的高斯函數,並在同一時間軸上應用平移和旋轉動畫。 示例存儲庫中提供了完整的源代碼。

使用經過修改的高斯函數時間映射的 Animation API 創建的動畫(大預覽)

特徵檢測

if (CSS.animationWorklet) { /* ... */ }

W3C 規範狀態

  • 第一個公共工作草案:準備好進行社區審查,容易發生規範變更

瀏覽器支持

谷歌瀏覽器微軟邊緣歌劇瀏覽器火狐蘋果瀏覽器
部分支持 (*) 部分支持 (*) 部分支持 (*) 不支持不支持

*支持啟用“Experimental Web Platform features”標誌。

數據來源:Houdini 準備好了嗎?

佈局 API

Layout API 允許開發人員通過定義可用於display CSS 屬性的新佈局模式來擴展瀏覽器的佈局呈現過程。 佈局 API 引入了新概念,非常複雜,並為開發自定義佈局算法提供了很多選項。

與其他 Worklet 類似,佈局 Worklet 需要先註冊和定義。

 registerLayout('exampleLayout', class { static get inputProperties() { return ['--exampleVariable']; } static get childrenInputProperties() { return ['--exampleChildVariable']; } static get layoutOptions() { return { childDisplay: 'normal', sizing: 'block-like' }; } intrinsicSizes(children, edges, styleMap) { /* ... */ } layout(children, edges, constraints, styleMap, breakToken) { /* ... */ } });

Worklet register 包含以下方法:

  • inputProperties
    Worklet 將跟踪的一組 CSS 自定義屬性屬於父佈局元素,即調用此佈局的元素。 該數組表示佈局工作集的依賴關係。
  • childrenInputProperties
    Worklet 將跟踪的一組 CSS 自定義屬性屬於父佈局元素的子元素,即設置此佈局的元素的子元素。
  • layoutOptions :定義以下佈局屬性:
    • childDisplay :可以有一個預定義的值blocknormal 。 確定框是顯示為塊還是內聯。
    • sizing :可以具有block-likemanual的預定義值。 它分別告訴瀏覽器預先計算大小或不預先計算(除非明確設置大小)。
  • intrinsicSizes :定義框或其內容如何適應佈局上下文。
    • children :父佈局元素的子元素,即調用此佈局的元素的子元素。
    • edges :盒子的佈局邊緣
    • styleMap : 框的類型化 OM 樣式
  • layout :執行佈局的主要功能。
    • children :父佈局元素的子元素,即調用此佈局的元素的子元素。
    • edges :盒子的佈局邊緣
    • constraints :父佈局的約束
    • styleMap : 框的類型化 OM 樣式
    • breakToken :用於在分頁或打印時恢復佈局的中斷令牌。

與 Paint API 的情況一樣,瀏覽器渲染引擎決定何時調用paint Worklet。 它只需要添加到 HTML 或主 JavaScript 文件中。

 CSS.layoutWorklet.addModule('path/to/worklet/file.js');

最後,它需要在 CSS 文件中引用

.exampleElement { display: layout(exampleLayout); }

Layout API 如何執行佈局

在前面的示例中, exampleLayout是使用 Layout API 定義的。

 .exampleElement { display: layout(exampleLayout); }

這個元素稱為父佈局,它包含在由內邊距、邊框和滾動條組成的佈局邊緣中。 Parent Layout 由稱為Current Layouts的子元素組成。 當前佈局是可以使用佈局 API 自定義佈局的實際目標元素。 例如,當使用display: flex; 在一個元素上,它的子元素被重新定位以形成 flex 佈局。 這類似於使用 Layout API 所做的事情。

每個Current Layout都由Child Layout組成,它是 LayoutChild(元素、 ::before::after偽元素)的佈局算法,而LayoutChild是一個 CSS 生成的框,僅包含樣式數據(無佈局數據)。 LayoutChild 元素由瀏覽器渲染引擎在樣式步驟中自動創建。 Layout Child 可以生成一個Fragment來實際執行佈局渲染動作。

例子

與 Paint API 示例類似,此示例直接從 Google Chrome 實驗室存儲庫導入砌體佈局 Worklet,但在此示例中,它用於圖像內容而不是文本。 示例存儲庫中提供了完整的源代碼。

Masonry 佈局示例(使用 Google Chrome Labs 的 Masonry Worklet(大預覽)

特徵檢測

if (CSS.layoutWorklet) { /* ... */ }

W3C 規範狀態

  • 第一個公共工作草案:準備好進行社區審查,容易發生規範變更

瀏覽器支持

谷歌瀏覽器微軟邊緣歌劇瀏覽器火狐蘋果瀏覽器
部分支持 (*) 部分支持 (*) 部分支持 (*) 不支持不支持

*支持啟用“Experimental Web Platform features”標誌。

數據來源:Houdini 準備好了嗎?

Houdini 和漸進增強

儘管 CSS Houdini 還沒有最佳的瀏覽器支持,但它現在可以在考慮漸進增強的情況下使用。 如果您不熟悉漸進式增強,那麼值得查看這篇解釋得很好的方便文章。 如果您今天決定在您的項目中實施 Houdini,請記住以下幾點:

  • 使用特徵檢測來防止錯誤。
    每個 Houdini API 和 Worklet 都提供了一種簡單的方法來檢查它是否在瀏覽器中可用。 使用功能檢測將 Houdini 增強僅應用於支持它並避免錯誤的瀏覽器。
  • 僅用於演示和視覺增強。
    在尚不支持 Houdini 的瀏覽器上瀏覽網站的用戶應該可以訪問網站的內容和核心功能。 用戶體驗和內容呈現不應該依賴於 Houdini 功能,應該有一個可靠的後備。
  • 使用標準的 CSS 後備。
    例如,常規 CSS 自定義屬性可用作使用自定義屬性和值 API 定義的樣式的後備。

首先專注於開發高性能和可靠的網站用戶體驗,然後將 Houdini 功能用於裝飾目的作為漸進式增強。

結論

Houdini API 最終將使開發人員能夠使用於樣式操作和裝飾的 JavaScript 代碼更接近瀏覽器的渲染管道,從而獲得更好的性能和穩定性。 通過允許開發人員連接到瀏覽器渲染過程,他們將能夠開發各種 CSS polyfill,這些 polyfill 可以很容易地共享、實現,並有可能添加到 CSS 規範本身中。 Houdini 還將使開發人員和設計人員在處理樣式、佈局和動畫時減少受 CSS 限制的限制,從而帶來令人愉悅的新 Web 體驗。

現在可以將 CSS Houdini 功能添加到項目中,但要嚴格考慮漸進增強。 這將使不支持 Houdini 功能的瀏覽器能夠無錯誤地呈現網站並提供最佳用戶體驗。

隨著 Houdini 獲得牽引力和更好的瀏覽器支持,開發者社區將提出什麼將是令人興奮的。 以下是來自社區的一些很棒的 Houdini API 實驗示例:

  • CSS Houdini 實驗
  • CSS Houdini 交互式介紹
  • Google Chrome 實驗室的 Houdini 示例

參考

  • W3C Houdini 規範草案
  • Houdini 狀態(Chrome 開發者峰會 2018)
  • Houdini 的動畫工作集 - Google Developers
  • CSS Houdini 交互式介紹