Playing with Houdini CSS, Part One — Introduction and PaintAPI

Eoin Falconer
Norigin Media Tech Blog
7 min readApr 11, 2018
Elkling as the code magician he truly is.

What is Houdini?

Houdini CSS is a new collection of browser APIs which allow you to gain more access to your browser’s CSS engine. The APIs are accessible through JavaScript, making them web developer friendly. Houdini is a W3C task force with the overriding goal of trying to make browser support issues a thing of the past. Houdini also attempts to resolve some of the more difficult things around CSS development, which is, at times, extremely delicate by nature. These series of articles are motivated by a lack of hands on tutorial explanations available out there for people looking to quickly have a look at Houdini and get playing around with it. I will be going through all 7 of them using any documentation I can find at time of writing.

Houdini CSS is currently comprised of 7 APIs, with each tackling a specific problem:

  • Paint API: Deals with background-image and background-border as CSS attributes, giving you the ability to draw in a canvas style on these images.
  • Typed OM API: We have all had to deal with splitting up strings to remove the ‘px’ so that we can get an integer value of a style. Typed OM takes care of all these values with this object-based API for working with CSS values in JavaScript.
  • Properties & Values API: Provides an API for defining CSS properties and giving them a type, behavior and default value. Very useful when paired with other APIs in this collection.
  • AnimationWorklet: This will solve the messy solution of watching for events such as scrolling and mouse movement inside the same thread that your UI is running. Enhancing user experience in a nifty API.
  • Layout API: My personal favorite. Build your own layouts, reinvent flexbox and grid and implement it all with one CSS style added.
  • Parser API: Make your own DOM element types such as <color> and have them do whatever you want to their children.
  • Font Metrics API: Exposing some font data to you in a digestible form which give you a lot more control over text in your application.

Wait, what’s the catch?

There is a catch, but luckily it’s only temporary. Currently browser support for Houdini is extremely low. Of the seven proposed APIs only 2 of them are available in standard Chrome (as of version 66) and a further three are partially working in Chrome Canary. The only other browser to begin development on Houdini is Firefox. Luckily, Google is leading the way here and more and more is being added in new releases of Chrome. So fear not, I don’t believe this is a pipe dream. If you want to keep up to date with Houdini browser support, use www.ishoudinireadyyet.com.

Browser support for Houdini at the time of writing this article. Source: www.ishoudinireadyyet.com

So, how do I play with it?

Whenever I am researching a new technology, the first thing I always do is try and play with it. When I first heard about Houdini, around 18 months ago I was intrigued but couldn’t really have any fun with it. Then, Houdini started being spoken about at conferences and people began to get a more concrete idea of what the task force’s mission is. With all this excitement came the first couple of APIs made available on Canary and I, for one, was really impressed.

The first thing you need to do is to go and download Google Chrome Canary. You can download it here. If you’re unfamiliar with Canary, it is basically a version of Chrome which has nightly updates from developers developing features for Chrome and some of these features haven’t even made it to Chrome Stable yet. You should also check out some of the other cool features which are hopefuls to make it to Chrome Stable in the future as there is tonnes of amazing things.

Then just open your favourite IDE/editor and let’s start playing.

Worklets

A worklet is basically what you will use to hook up to the CSS engine in the browser. These define the custom things that you want to be able to use in CSS. The cool thing about a worklet is that it feels almost plug in and play. You write your worklet, which does something and then it’s free to use in CSS. If you want to read more in depth about worklets check out this link, but as a use case, that is basically it for me.

My favourite thing about a worklet, however, is the performance. It has no impact on the performance of your other UI, because each worklet works inside its own thread, and that thread is spun up once you reference that worklet. This means that you get the smoothness of CSS that we’re all used to whilst also getting to use the prowess of JavaScript, pretty magic.

PaintAPI

The first API I will be looking at in this series is PaintAPI. PaintAPI shipped automatically enabled with Chrome Stable since Chrome 65. PaintAPI solves a problem which I personally have fought with consistently through my CSS development, background images. So, background images are a fairly common thing to implement, with background image you can use a color or an image. An image can be loaded using url(${image_url}) which is actually some pretty nifty syntax when you think about it. What PaintAPI does is it takes this syntax and gives us paint(${worklet}) .With this you’re able to draw on a background-image, the same was you would draw on a html <canvas> element and as mentioned before, this has no impact on your UI performance due to each worklet living on its own thread.

PaintAPI allows you to use a specific type of worklet called a paint worklet or CSS.paintWorklet. And yes, it is that simple, because you are just interacting with the browser, theCSS object is available to you at any point.

Let’s give this a try and start by drawing a simple circle inside of a <textarea>. The first thing you need to do is to write a simple html file. In this file we will have a <textarea> inside the body, and we will add a module called CirclePainter to our paintWorklet by using CSS.paintWorklet.addModule('circle.js') .

<!doctype html>
<html>
<head>
<title>Web Starter Kit</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<textarea></textarea>
<script>
CSS.paintWorklet.addModule('circle.js');
</script>
</body>
</html>

Now you need to create circle.js.

class CirclePainter {
paint(ctx, geom, properties) {
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(geom.height/2, geom.width/2 ,25 ,0 , 2*Math.PI);
ctx.fill();
}
}
registerPaint('circle', CirclePainter);

Here is some simple canvas drawing logic. ctx here is the context, this is pretty much the blank page you will be using, or the canvas itself. geo is the simple geometry of the context (width and height) and properties is what we will touch on in the next example, but you can probably already guess.

The interesting thing here is that we use registerPaint to assign the name circle to the class CirclePainter. We will then be able to use this in our CSS, which looks like this.

textarea {
width: 300px;
height: 300px;
background-image: paint(circle);
}

And the result you get from all that together:

Result of the code above. Shout out to Japan, kind of.

Now that we have a grasp over getting something on the screen, let’s play around with properties . Properties is basically an argument you hand in, but you can hand it in from CSS itself. Using custom properties you can hand in whatever you want to the paint function. Let’s have a look.

class CirclePainter {
static get inputProperties() {
return ['--circle-color']
}
paint(ctx, geom, properties) {
ctx.beginPath();
console.log("properties: ", properties.get('--circle-color'));
ctx.fillStyle = properties.get('--circle-color').toString();
ctx.arc(geom.height/2, geom.width/2 ,25 ,0 , 2*Math.PI);
ctx.fill();
}
}
registerPaint('circle', CirclePainter);

Here we use inputProperties to gain access to our property and we can then use that inside of our paint function to color the circle. Our CSS looks like the following and then you have a blue circle, all commanded from CSS.

textarea {
width: 300px;
height: 300px;
--circle-color: blue;
background-image: paint(circle);
}

You’re now ready to mess around with this really cool API. If you’re using custom properties make sure to use Chrome Canary and not Chrome Stable as they may not work due to the dependency on the Properties and Values API which isn’t available in Chrome Stable.

Until Next Time…

PaintAPI is the first Houdini CSS API that I will be talking about in this series. I am hoping that by the time to the end that a lot more support will be added.

The main takeaways from this first article is worklets for me. They underpin a lot of what makes Houdini cool under the hood. They deal with performance and accessibility but also readability and for me, readability is what makes CSS such a great language for anyone to get a quick grasp on and feel like you’re really building something and Houdini, so far, has been just that too!

>>>>> CHECK OUT PART 2 HERE

// Eoin Falconer, Frontend Developer at Norigin Media

--

--

Eoin Falconer
Norigin Media Tech Blog

Hi! My name is Eoin (Owen is the pronunciation you may be more familiar with). I am working as the CTO of Hospitality for Arribatec in Oslo, Norway.