【CSS】Houdini, CSS的成人礼
Houdini是一组低级API,使开发人员能够扩展CSS,提供了浏览浏览器渲染引擎的样式和布局过程的能力。Houdini使开发人员可以访问CSS对象模型(CSSOM),使开发人员能够编写浏览器可以解析为CSS的代码。Houdini的好处是开发人员可以创建CSS功能,而无需等待Web标准规范来定义它们,也无需等待每个浏览器完全实现这些功能。
前情提要
-
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)