【CSS】Houdini, CSS的成人禮
- 2019 年 10 月 3 日
- 筆記
前情提要

-
CSS:老闆,你看ES9,ES10都出來了,您看我的事情什麼時候…
-
W3C: 這不是正在走着流程嘛!小C你不要心急!
-
W3C:(語重心長)你看啊,我們先(1)提個開發提案章程, 然後再批准成立工作組(2)緊接着工作組建立標準和指南,然後再修改修改。(3)再然後啊,給顧問委員會技術報告審核一下(4)最後瀏覽器廠商再實現一下 這不就完事了嗎?大概不到10年咱們就全部搞定了吧
-
CSS: 。。。。。。 (難過)
-
W3C:(頓了頓):但是這些年啊,你的刻苦努力我們都是看在眼裡的!
-
CSS:所以!!??(興奮加期待)
-
W3C:所以啊,我們要感謝你為前端社區,所作出的貢獻!
-
CSS:。。。。。。(沮喪)
-
W3C:但是呢!考慮到你設備老舊,是該更新一下啦。
-
CSS:請問是!?(興奮加期待,還有微微的遲疑)
-
W3C:沒錯,這是老闆我送給你的步入成年的禮物—— Houdini
什麼是Houdini
S1. Paint API
background: paint(背景函數名);
S2.Layout API
display:layout(自定義布局名)
S3. AnimationWorklet
S4. Properties & Values
用於自定義CSS屬性並為其約定類型,行為和默認值。可以看作less的@式定義和Sass的$式定義的2.0加強版。順便一提,它經常和前3個API搭配使用。
S5. Parser API
S6.Typed OM
為什麼說Houdini是CSS的成人禮?
A. 為CSS新特性提供polyfill
B. Houdini的作用是為CSS提供進一步的完善
-
Paint API: 在JS領域裏直接使用Canvas標籤和包裝起來的相關函數也是可以做的
-
Layout API:提供的是大幅度的自定義布局的功能,但問題是。。。flexbox和grid已經把大多數場景給肝了。Layout要是早出來還好,這比flex完了這麼多年,就感覺有點尷尬
-
Typed OM:提供了直接操作CSS屬性的對象接口,但問題是CSSOM的標準出來也不少時間了呀,相比之下Typed OM的功能好像就失了一些新意。。。(某個表情包老頭估計會說:別筆筆,一梭子ele.style.cssText不就完事了嗎!)
-
其他,想到再更
-
CSS:大師!我感覺我在傳承了Houdini的靈力加持後功力大增!
-
大師:那尼瑪是因為你一開始的內力。。。emmm
啊~下面又到了我最喜歡的互懟環節了呀
為什麼說Houdini是CSS漫長的成人禮?


實戰Houdini之Paint API
// paint.js registerPaint('circle', class { // 決定了paint方法中props中能獲取的CSS屬性值 static get inputProperties() { return ['--color']; } // 繪製一個半徑為長或寬的最小值的圓形作為背景 // ctx是Canvas的ctx的子集,實現了除文字操作外的大多數方法和屬性 paint(ctx, size, props) { // size表示使用該paint方法的div的長和寬 const width = size.width / 2; const height = size.height / 2; const radius = Math.min(width, height); // props.get表示將根據inputProperties返回的鍵值從CSS代碼塊中獲取相應屬性 const color = props.get('--color'); // 給畫筆着色 ctx.fillStyle = color; // 開始動筆繪製 ctx.beginPath(); // 以width,height為圓心,radius為半徑畫圓圈,從0度畫到360度 ctx.arc(width, height, radius, 0, 2 * Math.PI); // 用fillstyle把圓圈軌跡內部進行顏色填充 ctx.fill(); // 搞定! } });
(代碼中的具體API我們過會再仔細解釋,我們先把代碼跑通再說)
CSS.paintWorklet.addModule('paint.js');
注意,paint.js內部會形成一個封閉而獨立的,叫worklet的作用域,它和全局Window是不一樣的!不要在這裡嘗試使用fetch等方法。
<!-- HTML --> <div class="foo"></div> <!-- CSS --> <style> .foo { border: 1px solid blue; width: 200px; height: 200px; /*指定背景色為紅色*/ --color: red; /*使用剛剛註冊的paint方法*/ background-image: paint(circle); } </style>
我們看下效果

https://github.com/penghuwan/houdini-module
registerPaint('circle', class { // ctx是Canvas的ctx的子集,實現了除文字操作外的大多數方法和屬性 paint(ctx, size, props) { // size表示使用該paint方法的div的長和寬 const width = size.width / 2; const height = size.height / 2; // ... } });
// paint.js registerPaint('circle', class { // 決定了paint方法中props中能獲取的CSS屬性值 static get inputProperties() { return ['--color']; } // ctx是Canvas的ctx的子集,實現了除文字操作外的大多數方法和屬性 paint(ctx, size, props) { const color = props.get('--color'); } }); // style .foo { /*指定背景色為紅色*/ --color: red; /*使用剛剛註冊的paint方法*/ background-image: paint(circle); }
警告,下面講的都是當前沒有任何stable瀏覽器可以運行的代碼,我是根據W3C的草案和示範代碼要求來的,正所謂——姜太公寫代碼,願者Debug
Layout
Animation
Propertis和values
Typed OM
CSS!你的Houdini來啦

但是你用不了,哈哈哈哈!

參考資料
-
layout的API草案(W3C)