Houdini and the Future of CSS [State of the Web]

Gepostet am: 09. September 2019

CSS is the styling language used to define the appearance of web contents. As web developers we rely on the existing implementation of CSS features across major browsers. Sometimes we face constraints that come with it, when a feature cannot be used in production because not every browser supports it. But with CSS Houdini this is about to change. Houdini’s goal is to enable web developers to extend the capabilities of CSS by providing APIs that make it possible to create custom CSS features and modify the browser rendering pipeline.

Houdini is a task force which consists of engineers from Google, Mozilla, Apple, Microsoft and others who work together on creating specification drafts that will be standardised by the W3C. These specifications define several APIs which contribute to the goal of making CSS more extensible. These APIs are usually referred to when spoken of Houdini.

This article will give you a brief overview of the Houdini specifications and their goal together with the current state of development.

Houdini Who?

Before we begin with the technical part, let’s take a brief look into the historical background. Harry Houdini (1874-1926) was a great american-hungarian illusionist and stunt performer, known best for his escape acts. He became famous for his handcuff-escapes including chains, straight jackets and escapes from under water while holding his breath.

The CSS Houdini Task Force took up his name, as their goal is to create a technology that enables developers to explore and understand the „magic“ behind CSS styling and layouting algorithms.

  

The Specs

The Houdini specifications consist of several browser APIs that are shipped separately, where each one in its own right contributes to making CSS more extensible. Whereas some APIs have already shipped in some of the modern browsers, others are more of a summary of interesting ideas. But all of them help us gain perspective of what the future of CSS will look like and the general direction in which the web platform is developing.

Unfortunately Houdini still is in early stages of development. At the time of writing this article the APIs are available mainly in Chrome and other Chromium-based browsers including Opera and soon Microsoft Edge as well. Other browser vendors are yet to implement Houdini. ishoudinireadyyet offers a handy overview of the development stages of the Houdini API in major modern browsers.

The following sections cover the core features of each of the Houdini APIs with a brief description.

Web Worklets

Web Worklets are not very useful alone, they are more of a technical concept that is necessary in order to create hooks inside of the browser’s rendering engine and provide custom functionality. Worklets are JavaScript execution environments that can be spawned across multiple threads and run concurrently to the main thread. This allows for better performance and isolation.

Web Worklets are similar to Web Workers, however they are more lightweight. Which they must be considering that in some cases they have to be executed every single frame. Web Worklets have a much smaller scope, which is usually limited to the exact purpose of the specific worklet type. In order for the browser to be able to execute the worklet code, it must be registered on the JavaScript main thread. Once the worklet is registered, it can be called by the browser whenever it parses a CSS property that uses this worklet. Then the rendering engine will trigger the appropriate worklet thread. The browser also decides how many worklet threads are spawned in order to optimize the resources depending on their usage.

CSS Paint API

CSS Paint API (a.k.a The Paint Worklet) allows you to programmatically draw anything where CSS expects an image. Similar to loading an image via url() it is now possible to generate an image using the paint function and a paint worklet. For example to draw a custom background image: background-image: paint(customPaint). The paint worklet must provide an algorithm, which defines which graphics will be drawn, using an API similar to the rendering context in HTML Canvas. The browser will run the worklet algorithm whenever it is used in CSS and then render its output for the according elements on the page. The worklet code will be executed independently from the main thread, thus relieving the main thread from having to run these computations and allowing it to handle user input and run other scripts faster.

For a more in-depth introduction and step by step example I recommend reading this article by  Surma. The Paint API is very flexible and allows developers to draw practically anything including svg-like graphics, gradients and things like multiple borders (that are not yet supported natively in CSS). Which leads to probably the most exciting feature of Houdini in general: the possibility of efficient „native“ polyfilling of CSS features, as worklets are being hooked directly into the rendering pipeline.

CSS Layout API

Layout API (a.k.a Layout Worklet) makes it possible to create custom layouting algorithms that can be applied via the CSS display property to an element and its children. The browser will handle the worklet the same way it does with the standard display modes (such as flexbox, css grid or table mode) however here it will use the algorithm provided by the web developer to determine the position and offset of the element.

Similar to the Paint API, the Layout API also relies on layouting logic being provided via a worklet. The Layout Worklet will be hooked into the layouting stage of the rendering pipeline and called whenever the browser parses a display property which uses this worklet display: layout(myFancyLayout).

Probably the most anticipated example using the Layout API is to create a masonry layout using a worklet, which currently is only possible via (main-thread) JavaScript.

The example shows the masonry layout demo implementation from GoogleChromeLabs.

CSS Animation API

Animation API (a.k.a Animation Worklet) creates another hook into the rendering pipeline, this time into the compositing step. The Animation API enables developers to implement highly performant animation effects that are tied to user input events such as scrolling. The main goal is to create a method for low-latency visual feedback. The response time is crucial for good user experience, because even a slight delay is perceived by users as slow and janky.

In order to create smooth animations in direct sync with user input the worklet is executed independent from the main thread to make the compositor generate frames at the highest frame rate possible (hopefully 60fps). The Animation API uses the Web Animations API to describe the animations‘ behaviour.

For an in depth description of the core mechanics of the Animation API I highly recommend reading this article. It does a great job in explaining how exactly user input can be translated into animation timeline seamlessly.

CSS Typed OM

CSS Typed OM is a successor of the previous string-based API for querying and modifying CSS properties of an element in JavaScript. As the name suggests the new Typed CSS Object Model exposes the style information, where the values are represented in the form of typed JavaScript objects instead of strings which allows usage with less performance loss due to string manipulation. My colleague Sven Lindauer wrote an article about the CSS Typed OM where he compared it to the older string-based CSSOM, so head over there for examples.

Properties and Values API

So far CSS variables were kind of like placeholders and could carry only string values. The Properties and Values API lets us not only specify a custom CSS property but also tell the CSS parser how it should interpret its value using the syntax description with the type of the property whether it is supposed to be inherited by the child elements and its default value. This is a JavaScript API and there is a proposal to include support for a declarative CSS API.

The following code sample illustrates usage of the JavaScript API to register a custom CSS property –my-color. The custom property can then be used in regular CSS.

The most exciting feature of this specification is that it can be used in combination with worklets to create an input parameter for the worklet function. In worklets we can query the elements style map which contains all computed CSS properties, containing both native and custom CSS properties.

CSS Parser API

CSS Parser API will allow web developers to use the browser-internal CSS parser to parse strings containing CSS into a typed JavaScript object representation. Currently the single option to parse strings into CSS and vice versa is through a third-party library. This feature is most interesting in the context of polyfilling, as it will offer significant performance improvements for processing CSS.

Polyfills allow developers to use features, that aren’t (yet) natively supported by the browsers. A polyfill would modify the stylesheets by replacing the unsupported syntax using analogies that the browser can understand. A polyfill script would query every style definition on a web page found in stylesheets, <style> tag and inline style-attributes, modify these definitions and then insert them back into the DOM. In order for a polyfill to be able to modify the stylesheets they first need to be serialized. Polyfills rely on third-party libraries to parse these string-based style definitions into JavaScript objects.

This is one of the reasons why CSS polyfilling is bound to have poor performance at runtime. In his article Philip Walton describes the biggest pains of CSS polyfills in browsers and how Houdini can help improve them. The article is already a couple of years old, but it’s still highly informative for anyone who wants to gain a deeper understanding of CSS polyfilling in browser and the challenges associated with it.

These were a lot of APIs! But we haven’t even mentioned Font Metrics or Box Tree API yet—that is because those are in very early stages of development. If you are looking for the newest updates on the spec make sure to visit the CSS-TAG Houdini Editors Drafts homepage.

What’s Next?

We have looked into the CSS Houdini task force and got to know its APIs. Houdini’s aim is to provide a low level access to CSS processing and the browser rendering pipeline, and by that allowing us to modify and extend CSS functionality. So where does that leave us today?

Some see Houdini as the most exciting development in CSS for its potential to greatly influence the way new features are introduced into CSS by allowing people to invent their own features, adressing many pain points of the CSS we know today.

But still we are not there yet. The APIs are currently just experimental browser features implemented mostly in Chrome and other Chromium-based browsers such as Opera and future versions of Edge. Firefox and Safari have both shown an intent to implement them, but it is yet unclear how long it will take them to fully implement the features. It will take a long time for Houdini to become ready for production use.

However having these APIs in Chrome means that we can experiment and try out these features today and I highly encourage everybody to do so. Houdini APIs are very fun to play with and because they are very low level you are most certainly learning a lot about internal browser  functionality doing so.

When Houdini becomes available in all browsers, because of its low level nature, you are most likely not going to use these APIs directly when developing a web application. The same way you probably wouldn’t start building a layouting library from scratch, you are most likely not going to implement a custom layouting system using a Layout Worklet, but instead use an existing one and import it in your project. This is where Houdini will come to use. It will open up great possibilities for libraries and polyfills authors, by allowing them to register custom hooks directly into the rendering pipeline and let the browser take care of these computations independent from the main thread and create polyfills that perform at render engine speed. Houdini will enable web developers to invent brand new CSS features and spread them as installable worklets. The possibilities are almost endless.

I hope this article was helpful and offered some new insights into the extravaganza that is CSS Houdini. You will find additional resources attached below. Please feel free to contact me here or on twitter @tanja_uli if you have any questions or want to share your thoughts on Houdini or simply to say hi.

Further Resources

State of Houdini (Chrome Dev Summit 2018) talk by Surma

CSS Houdini & The Future of Styling by Una Kravets

A Curated List of Houdini Resources on github

Image sources

[1],[2],[3]

Read on

Find out more about our web services or consider joining us as a web dev yourself!

2019-09-09T14:07:56+00:00

Hat dir der Beitrag gefallen?