preface

Houdini is a major revolution in CSS. The ultimate goal of Houdini is to achieve full compatibility of CSS properties. One of the most interesting features of Houdini is its ability to correctly polyfill CSS! This is quite abstract. What does it do and how to use it? This article will explain one or two.

The basic concept

Houdini is a set of low-level apis that expose parts of the CSS engine and enable developers to extend CSS by hooking into the styling and layout processes of the browser rendering engine. It gives developers direct access to the CSS object Model (CSSOM), enabling developers to write code that the browser can parse into CSS to create new CSS features without waiting for those features to implement themselves in the browser.

In addition, it can be used to create custom CSS properties with type checking and default values.

Houdini API is introduced

CSS Property and values API

CSS already has custom properties, which unlock a lot of new gameplay. The CSS Properties and Values API further promotes custom Properties, allowing different types to be added to custom Properties, allowing property type checking, setting default Values, and defining whether a property can inherit Values, greatly increasing the ability to customize Properties.

The main selling point of the API is that developers can animate custom properties, which is not possible with current technology alone.

Let’s start with an example. CSS variables are probably used by a lot of people, and they’re amazing because they’re dynamic. But one of its weaknesses is that it can’t be converted; if you try to animate a variable, it just flips from one property to another, with no transition effect.

Codepen Demo

This is because CSS changes don’t make any sense, it doesn’t have any type, so the browser doesn’t know if a particular variable is 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'
})
Copy the code

The CSS Houdini’s Properties and Values API allows us to specify CSS variablestype. With strongly typed CSS variables, it can eventually be converted. One of the most popular use cases is animated gradients.

Codepen Demo

There are two ways to use it

1. Define CSS properties in the CSS@property

@property --my-color {
  syntax: '<color>';
  inherits: false;
  initial-value: #c0ffee; } // use:div {
  color: var(--my-color);
}
Copy the code

Property –property-name in @property –property-name indicates the name of a user-defined attribute. After the attribute is defined, it can be referenced by var(–property-name) in the CSS

  • Syntax: The syntax rule for this custom attribute, which can also be understood as the type of the custom attribute defined
  • Inherits: Whether or not inherits are allowed
  • Initial-value: indicates the initial value

2. Define CSS properties in JSCSS.registerProperty

window.CSS.registerProperty({
  name: '--my-color'.syntax: '<color>'.inherits: false.initialValue: '#c0ffee',})// use in CSS
div {
  color: var(--my-color);
}
Copy the code

CSS Paint API

This API enables us to programmatically create images for any CSS property that requires an image through Canvas. Examples of such attributes are background-image and border-image.

The CSS Paint API can be simply interpreted as using Canvas as the background of a common element. In other words, CSS background-image is a Canvas. You can use this feature to draw background effects for many elements.

The small sample

Let’s write a checkerboard background for the Textarea as follows:

<! -- index.html -->
<! doctypehtml>
<style>
  textarea {
    background-image: paint(checkerboard);
  }
</style>
<textarea></textarea>
<script>
  CSS.paintWorklet.addModule('checkerboard.js');
</script>
Copy the code
// 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++) {
        constcolor = 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);
Copy the code

Codepen Demo

Its fixed usage is divided into three steps:

  1. CSS paint (ABC);
  2. JS add module CSS. PaintWorklet. AddModule (‘ XXX. JS);
  3. XXX. Js code routine is fixed, in the comments below to write the drawing code;
registerPaint('abc'.class {
    paint(context, size, properties, args) {
       // Draw the code here at....}});Copy the code

The registerPaint method registers a Paint class ABC to call. The core of this class is its Paint method. The paint method is used to describe custom draw logic and takes four parameters:

  • Context: The context of the drawing, the API is all coming from the CanvasCanvasRenderingContext2DFor security reasons, some Canvas apis are not available.
  • Size: the size information of the node, which is also the size information of the canvas’s drawable scope (artboard).
  • Properties: Contains the CSS properties of the node and requires a static method called inputProperties to declare injection.
  • Args: Arguments passed in CSS when the Paint class is called. You need to call the static method inputArguments to declare injection.

summary

The CSS Paint API is suitable for dynamic scenes that need to be rendered in real time; If it is static, it can be implemented directly with JS+Canvas. CSS Houdini is not necessary.

CSS Typed OM

When we changed the DOM element style, we were actually working with the CSS object model CSSOM. CSSOM is simply an API that allows JS to manipulate element styles:

const el = document.getElementById('el');
el.style.opacity = 0.3;
Copy the code

The type el.style.opacity is not a number, but a string. If it is to be mathematically computed, it needs to be Typed first, so this is the problem Typed OM is solving.

Converting a CSSOM value string to a meaningful typed JavaScript representation and returning it can result in significant performance overhead. The specification exposes CSS values as typed JavaScript objects to make manipulating them easier and higher performance.

Its selling points include:

  1. CSSOM performance has been further improved due to the reduction of string operations. Tests provided by Tab Akins (Github user) show that Typed OM operations are about 30% faster than CSSOM strings.
  2. Error handling, which throws an error for the wrong CSS value;
  3. The simple arithmetic operation method can be called on the numerical object, and the unit conversion can be done easily between the absolute units.

Read and assign usage

In Typed OM, the number and the unit of the number are separated. It gets a CSSUnitValue object with two internal keys: value and unit.

To assign a style to an element, you can also accept strings in addition to using css.px constructs
el.attributeStyleMap.set('height', CSS.px(10));
el.attributeStyleMap.set('height'.'10px');

// For fetch, return the CSSUnitValue object, whose value property is accessed to obtain a numeric value
el.attributeStyleMap.get('height').value; / / 10
el.attributeStyleMap.get('height').unit; // 'px'
Copy the code

Other uses self exploration.

meaning

The use of Typed OM is laying the foundation for the more efficient development of various Houdini standards, including custom attributes, layout and drawing standards.

CSS Typed OM solves the problem of modifying values at development time. It also increases the overall performance by reducing the number of string operations, making CSSOM easy and efficient to manipulate. RequestAnimationFrame can also produce custom animations with better performance.

CSS Layout API

The CSS Layout API is known for letting developers customize layouts, such as waterfall streams. Let the Web layout have more imagination space, because the browser is not fully open to developers, and the cost of learning is high, CSS and JS at the same time have certain attainments to control, so this article does not do.

Parsing AP

Not written into the specification, this article does not expand.

The relevant worklets

There is a script written to registerPaint that references it using Worklets!

Worklet is a very lightweight and highly specialized worker. It allows developers to do hooks in multiple parts of the browser rendering thread. Worklets are similar in concept to Web workers in that they allow you to import script files and execute specific JS code that meets two conditions: first, it can be called in the rendering process; Second, independence from the main thread (performance improvement). Basic usage:

CSS.paintWorklet.addModule('myWorklet.js');
Copy the code

Myworklet.js can then be referenced by the browser and executed internally, independently of the main thread!

Write in the last

It’s hard for developers to interfere with the browser rendering process, except for DOM and CSSOM. With Houdini we can interfere with browser parsing, and it can do several things for framework authors and developers:

  • Improving Web Performance
  • Unify cross-browser behavior
  • Develop or patch new features
  • other

Since CSS has no runtime state, normally we modify the DOM with JS to cause the page to be re-rendered, which can cause performance issues. Houdini allows developers to access the browser rendering engine, which is at the heart of all Houdini apis!

Reference

  • drafts.css-houdini.org/
  • zhuanlan.zhihu.com/p/47012322
  • Aysha. Me / 2019/08 / CSS…
  • www.zhangxinxu.com/wordpress/2…