This article was first published on Nuggets , reprinting without permission is strictly prohibited
Preface
I recently studied Houdini. It is a major change in the CSS field. Its ultimate goal is to achieve full compatibility of CSS properties. One of the most concerned features is that it can correctly polyfill CSS! This is more abstract. What exactly does it do and how to use it? This article will explain one or two.
basic concepts
Houdini is a set of low-level that expose part of the 161cb035e02b4e CSS engine , enabling developers the style and layout process of the hook
to the browser rendering engine 161cb035e02b52. It allows developers to directly access the CSS Object Model (CSSOM), enabling developers to write code that the browser can parse into CSS, thereby creating new CSS features without waiting for these features to be implemented in the browser.
In addition, it can also be used to create some custom CSS properties with type checking and default values.
Houdini API introduction
One, CSS property and value API
CSS actually already has custom properties, which can unlock too many new ways to play. The emergence of the CSS Properties and Values API further promotes custom properties. It also allows the addition of different types of custom properties, allows property type checking, setting default values, and defining whether properties can inherit values, greatly increasing the ability of custom properties.
The biggest selling point of this API is that developers can make animations on custom attributes, which is impossible with current technology.
Let's look at a case first. CSS variables may have been used by many people. The reason why they are magical is that they are dynamic. But one of its weaknesses is that it cannot be converted. If you try to animate a variable, it will only flip from one property to another without transition effects.
This is because CSS has changed and has no meaning, it has no type, so the browser does not know whether a particular variable is a color, percentage, number, etc.
CSS Houdini provides the ability to assign types to variables. If you assign a value of the wrong type to a variable, the browser will ignore it and choose the default value.
CSS.registerProperty({
name: '--start',
syntax: '',
inherits: true,
initialValue: 'purple'
})
CSS Houdini's Properties and Values API allow us to specify type for CSS variables. Using strongly typed CSS variables, it can eventually be converted. One of the most popular use cases is animated gradients.
There are 2 ways to use
1. Define CSS property @property
@property --my-color {
syntax: '<color>';
inherits: false;
initial-value: #c0ffee;
}
// 使用:
div {
color: var(--my-color);
}
@property --property-name
in --property-name
is the name of the custom attribute. After definition, it can be referenced var(--property-name)
- syntax: The grammatical rules of the custom attribute can also be understood as the type of the defined custom attribute
- inherits: whether to allow inheritance
- initial-value: initial value
2. Define CSS property CSS.registerProperty
window.CSS.registerProperty({
name: '--my-color',
syntax: '<color>',
inherits: false,
initialValue: '#c0ffee',
})
// css中使用
div {
color: var(--my-color);
}
2. CSS Paint API (Worklets)
This API allows us to programmatically create an image for any CSS property that requires an image Canvas
Examples of such attributes are background-image
and border-image
.
CSS Paint API can be simply understood as using Canvas
as the background image of ordinary elements. That is to say, the background-image
CSS is a Canvas
. You can use this feature to draw background effects for many elements.
Small example
Below we textarea
, the effect is as follows:
<!-- 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);
Its fixed usage routine is divided into three steps:
- Paint(abc) in CSS;
- JS add module CSS.paintWorklet.addModule('xxx.js');
The code routine in xxx.js is fixed, just write the drawing code in the comment position below;
registerPaint('abc', class { paint(context, size, properties, args) { // 绘制代码在这里.... } });
The registerPaint method registers a Paint class abc for calling. The core of this class lies in its
paint
method.paint
method is used to describe custom drawing logic. It receives four parameters:- context: the context of drawing, all APIs are from
CanvasRenderingContext2D
Canvas, but due to security restrictions, some APIs in Canvas cannot be used. - size: The size information of the node, which is also the size information of the canvas drawable range (artboard).
- properties: Contains the CSS properties of the node, you need to call the static method inputProperties to declare the injection.
- args: The parameters passed in when calling the Paint class in CSS, you need to call the static method inputArguments to declare injection.
Three, CSS Typed OM
In the past, we modified the style of DOM elements, but in fact we are operating the CSS object model CSSOM. In short, CSSOM is an API that allows JS to manipulate element styles:
const el = document.getElementById('el');
el.style.opacity = 0.3;
There will be a problem el.style.opacity
The type of 061cb035e02eff is not a number, but a string. If you want to perform mathematical calculations on it, you need to perform type conversion first, so this is the problem Typed OM wants to solve.
Converting CSSOM value strings into meaningful typed JavaScript representations and back can cause significant performance overhead. The specification exposes CSS values as typed JavaScript objects to make manipulating them easier and more performant.
Its selling points are:
- Better performance, due to the reduction of string operations, the operation performance of CSSOM has been further improved. The test provided by Tab Akins (github user) shows that operating Typed OM brings more benefits than directly operating CSSOM strings Approximately 30% speed increase;
- Error handling, for wrong CSS values, an error will be thrown;
- Call simple arithmetic operation methods on numerical objects, and it is convenient to convert between absolute units;
Read and assign usage
In Typed OM, the value and the unit of the value are separated, and what is obtained is a CSSUnitValue
object with two built-in keys: the value
and the unit 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'
Self-exploration of other usages.
summary
The meaning of Typed OM to other Houdini APIs: The use of Typed OM lays the foundation for the more efficient development of various Houdini standards in the future, including custom attributes, layout and drawing related standards.
CSS Typed OM solves the problem of modifying the value of , and at the same time to increase the overall operating performance , which makes us not only convenient but also efficient in operating CSSOM, and with requestAnimationFrame
can also create a better performance. Define the animation.
Four, CSS Layout API
The signature of the CSS Layout API is to allow developers to customize the layout, such as waterfall flow. Let the Web layout have more room for imagination. Because the browser has not been fully opened to developers, and the learning cost is high, it requires both CSS and JS to have certain attainments to control, so this article will not expand.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。