本文首发于掘金,未经许可严禁转载
前言
最近钻研了下 Houdini,它是 CSS 畛域的一个重大改革,它的终极目标是实现 CSS 属性的齐全兼容,其中最受关注的个性之一就是它能正确地 polyfill CSS!这么说比拟形象,它到底是做什么的呢,如何应用呢,本文来解说一二。
基本概念
Houdini 是一组底层 api,它公开了 CSS 引擎 的局部内容,使开发人员可能通过 hook
到浏览器 渲染引擎 的款式和布局过程来扩大 CSS。它能够让开发者间接拜访 CSS 对象模型(CSSOM),使开发者可能编写浏览器能够解析为 CSS 的代码,从而创立新的 CSS 个性,而无需期待这些个性在浏览器中自行实现。
此外,它还能用于发明一些自定义的,带有类型检查和默认值的 CSS 属性。
Houdini API 介绍
一、CSS property 和值 API
CSS 其实曾经有自定义属性了,这能解锁太多新玩法。而 CSS Properties and Values API 的呈现进一步推动自定义属性,还容许自定义属性增加不同的类型,容许属性类型查看、设置默认值以及定义属性是否能够继承值,大大增加自定义属性能力。
这个 API 最大卖点是 开发者能够在自定义属性上做动画,这是仅凭借当初技术是做不到的。
先来看一个案例,CSS 变量可能很多人都有应用过,它之所以神奇,是因为它是动静的。但它的弱点之一是无奈转换,如果你尝试为变量设置动画,它只会从一个属性翻转到另一个属性,之间没有过渡成果。
Codepen Demo
这是因为 CSS 变了没有任何意义,它没有任何类型,因而浏览器不晓得特定变量是否是色彩、百分比、数字等。
CSS Houdini 提供了为变量调配类型的能力。如果你为变量调配了谬误类型的值,浏览器将疏忽它并抉择默认值。
CSS.registerProperty({
name: '--start',
syntax: '',
inherits: true,
initialValue: 'purple'
})
CSS Houdini’s Properties 和 Values API 容许咱们为 CSS 变量指定 类型。应用强类型的 CSS 变量,它最终能够被转换。最风行的用例之一是动画突变。
Codepen Demo
应用形式有 2 种
1、CSS 中定义 CSS 属性 @property
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: #c0ffee;
}
// 应用:div {color: var(--my-color);
}
@property --property-name
中的 --property-name
就是自定义属性的名称,定义后可在 CSS 中通过 var(--property-name)
进行援用
- syntax:该自定义属性的语法规定,也能够了解为示意定义的自定义属性的类型
- inherits:是否容许继承
- initial-value:初始值
2、JS 中定义 CSS 属性 CSS.registerProperty
window.CSS.registerProperty({
name: '--my-color',
syntax: '<color>',
inherits: false,
initialValue: '#c0ffee',
})
// css 中应用
div {color: var(--my-color);
}
二、CSS Paint API(Worklets)
该 API 使咱们可能通过 Canvas
以编程形式为须要图像的任何 CSS 属性创立图像。此类属性的示例是 background-image
和 border-image
。
CSS Paint API 能够简略了解为把 Canvas
作为一般元素的背景图,也就是说 CSS 的 background-image
就是一个 Canvas
,能够利用这个个性为很多元素绘制背景特效。
小示例
上面咱们为 textarea
写一个棋盘背景,成果如下:
<!-- index.html -->
<!doctype html>
<style>
textarea {background-image: paint(checkerboard);
}
</style>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {paint(ctx, geom, properties) {
// Use `ctx` as if it was a normal canvas
const colors = ['red', 'green', 'blue'];
const size = 32;
for(let y = 0; y < geom.height/size; y++) {for(let x = 0; x < geom.width/size; x++) {const color = colors[(x + y) % colors.length];
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(x * size, y * size, size, size);
ctx.fill();}
}
}
}
// Register our class under a specific name
registerPaint('checkerboard', CheckerboardPainter);
Codepen Demo
它的固定用法套路分三步走:
- CSS 中 paint(abc);
- JS 增加模块 CSS.paintWorklet.addModule(‘xxx.js’);
-
xxx.js 中代码套路固定,在上面正文地位写绘制代码即可;
registerPaint('abc', class {paint(context, size, properties, args) {// 绘制代码在这里....} });
registerPaint 办法注册了一个 Paint 类 abc 以供调用,这个类的外围在于它的
paint
办法。paint
办法用于形容自定义的绘制逻辑,它接管四个参数: - context:绘图的上下文,API 全部都是来自 Canvas 的
CanvasRenderingContext2D
,不过为了平安限度,有些 Canvas 中的 API 是不能应用的。 - size:节点的尺寸信息,同时也是 canvas 可绘制范畴 (画板) 的尺寸信息。
- properties:蕴含节点的 CSS 属性,须要调用静态方法 inputProperties 申明注入。
- args:CSS 中调用 Paint 类时传入的参数,须要调用静态方法 inputArguments 申明注入。
三、CSS Typed OM
以前咱们批改 DOM 元素款式,实际上咱们操作的是 CSS 的对象模型 CSSOM。而 CSSOM 简略说就是能让 JS 操作元素款式的 API:
const el = document.getElementById('el');
el.style.opacity = 0.3;
这会存在一个问题 el.style.opacity
的类型并非一个数字,而是一个字符串。如果要像将其进行数学计算,那就须要先进行类型转换,所以这就是 Typed OM 要解决的问题。
将 CSSOM 值字符串转换为有意义的类型化 JavaScript 示意并返回可能会导致显着的性能开销。该标准将 CSS 值公开为类型化的 JavaScript 对象,以使操作它们更容易且性能更高。
它的卖点有:
- 更好的性能,因为缩小了字符串操作,对于 CSSOM 的操作性能失去了更进一步的晋升,由 Tab Akins(github 用户)提供的测试表明,操作 Typed OM 比间接操作 CSSOM 字符串带来了大概 30% 的速度晋升;
- 错误处理,对于谬误的 CSS 值,将会抛出谬误;
- 在数值对象上调用简略的算术运算办法,相对单位之间还能不便得尽兴单位转换;
读取和赋值用法
在 Typed OM 中,数值和数值的单位是离开的,所获取的是一个 CSSUnitValue
对象,内置数值 value
和单位 unit
两个键。
// 要对一个元素的款式赋值,除了能够应用 CSS.px 构建之外,还能承受字符串
el.attributeStyleMap.set('height', CSS.px(10));
el.attributeStyleMap.set('height', '10px');
// 对于获取,返回 CSSUnitValue 对象,拜访其 value 属性即可失去数字类型的值
el.attributeStyleMap.get('height').value; // 10
el.attributeStyleMap.get('height').unit; // 'px'
其它用法自性摸索。
小结
Typed OM 对于其它 Houdini API 的意义:Typed OM 的应用在为往后更高效地倒退各个 Houdini 规范打下了根底,包含自定义属性,布局以及绘制相干规范。
CSS Typed OM 解决了 开发时批改数值的问题 ,同时通过 缩小字符串操作减少了总体的操作性能,使得咱们在操作 CSSOM 不仅不便还高效,配合 requestAnimationFrame
还能制作出性能更优的自定义动画。
四、CSS Layout API
CSS Layout API 的招牌就是让开发者自定义布局形式,比方瀑布流等。让 Web 布局有更多的设想空间,因为浏览器还没有齐全凋谢给开发者,并且学习老本较高,须要 CSS 和 JS 同时具备肯定造诣能力驾驭,因而本文不做开展。
Reference
- https://drafts.css-houdini.or…
- https://zhuanlan.zhihu.com/p/…
- https://aysha.me/2019/08/css-…
- https://www.zhangxinxu.com/wo…