Next-gen CSS with Houdini
Tags: css, webdev
Published: 2020-09-10 19:28:54

In a more and more extensible web, CSS seams sometimes a bit outdated. 

Thanks to Houdini developers will be able to access low level APIs that exposes parts of the CSS engine. With Houdini, it is possible to hook into the styling and layout process of a browser's rendering engine. 

**In simple words, CSS Houdini enables developers to tie in the CSS API to add new functionalities.**


Note that this post is only a short summary of all the APIs with a brief explanation. If you are interested in the subject and want more in-depth information check out the articles of [Surma](https://twitter.com/DasSurma) and the links at the end of the post. 

## Houdini's APIs

### Layout API
*Add custom layout algorithms to the native browser algorithms.*

Example: masonry layout.
```css
.gallery{ display: layout(masonry); }
```

### Paint API
*Draw directly into an elements background, border, or content.*

Example: rainbow border.
```css
.rainbow{ background-image: paint(rainbow); }
```

### Parser API
*Access the parser engine.*

Use cases: 
1. Pass the parser a string and receive an object to work with instead of building custom parsing in JS.
2. Extend what the parser understands for fully polyfilling.

### Properties & Values API
*Register custom proprieties so that the browser knows what it should be.*

Custom proprieties do not have a type and can be wrongly overridden: 
```css
.box{
  --primary-color: 3px;
  color: var(--primary-color); // Wrong!
}
```
In that case the browser does not know that `--primary-color` has not a valid value. The solution with Houdini would be to register the propriety:
```js
window.CSS.registerProperty({
   name: '--primary-color',
   syntax: '<color>',
   inherits: false,
   initalvalue: 'red'
});
```

### AnimationWorklet
*Allows the developer to write imperative animations that run at the device's native frame rate.* 

Very interesting is the fact that you can link the animation to scroll instead of time (e.g. a parallax effect)

This example moves a box with the vertical scroll of a given element:
```js
new WorkletAnimation(
  "moveVertically",
  new KeyframeEffect(
    document.querySelector("#box"),
    [
      { transform: "translateY(0)" },
      { transform: "translateY(300px)" }
    ],
    { 
      duration: 4000,
      fill: "both"
    }
  ),
  new ScrollTimeline({
    scrollSource: document.querySelector("#container"),
    orientation: "vertical",
    timeRange: 2000
  })
).play();
```
 
### Typed OM
*API for the CSSSOM exposing the CSS values as typed JavaScript object rather than strings.*

- Allows the performant manipulation of values assigned to CSS proprieties. 
- Write more maintainable code.

```js
// with CSSOM
element.style.height; // "42", a string :(

// with Typed OM
element.attributeStyleMap.set('height', CSS.px(42));
const height = element.attributeStyleMap.get("height")
console.log(height.value); // 42, a number :D
console.log(height.unit); // "px", a string
```

###Font Metrics API
*This API is designed to provide basic font metrics both in-document and out-of-document content.*

With the Front Metrics API a developer will be able to measure the dimensions of text elements and affect how they will be displayed on the screen.


## Is Houdini ready yet?

No. You can use Houdini to experiment in your own projects but most browsers do not support CSS Houdini. 

![Is Houdini ready yet?](https://dev-to-uploads.s3.amazonaws.com/i/ol9he0nskw4jr33gfihz.jpg)
[View website](https://ishoudinireadyyet.com/)

## More info & credits
- [https://developer.mozilla.org/en-US/docs/Web/Houdini](https://developer.mozilla.org/en-US/docs/Web/Houdini)
- [https://ishoudinireadyyet.com/](https://ishoudinireadyyet.com/)
- [https://github.com/w3c/css-houdini-drafts/](https://github.com/w3c/css-houdini-drafts/)
- [https://web.dev/css-props-and-vals/](https://web.dev/css-props-and-vals/)
- [https://developers.google.com/web/updates/2018/03/cssom](https://developers.google.com/web/updates/2018/03/cssom)
- [https://drafts.css-houdini.org/font-metrics-api/](https://drafts.css-houdini.org/font-metrics-api/)
- [https://dev.to/adrianbdesigns/css-houdini-worklets-paint-api-and-font-metrics-api-mj4](https://dev.to/adrianbdesigns/css-houdini-worklets-paint-api-and-font-metrics-api-mj4)
- [https://developers.google.com/web/updates/2018/10/animation-worklet](https://developers.google.com/web/updates/2018/10/animation-worklet)