CSS Painting API
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimental:This is anexperimental technology
Check theBrowser compatibility table carefully before using this in production.
The CSS Painting API — part of theCSS Houdini umbrella of APIs — allows developers to write JavaScript functions that can draw directly into an element's background, border, or content.
In this article
Concepts and usage
Essentially, the CSS Painting API contains functionality allowing developers to create custom values forpaint(), a CSS<image> function. You can then apply these values to properties likebackground-image to set complex custom backgrounds on an element.
For example:
aside { background-image: paint(my-painted-image);}The API defines aworklet that can be used to programmatically generate an image that responds to computed style changes. To find out more about how this is used, consultUsing the CSS Painting API.
Interfaces
PaintWorkletGlobalScopeThe global execution context of the paint worklet.
PaintRenderingContext2DThe rendering context for the CSS Painting API's rendering context for drawing to the bitmap.
PaintSizeRepresents the size of the output bitmap that the author should draw.
Examples
The following example creates a list of items with a background image that rotates between three different colors and three widths.Ina supporting browser you will see something like the image below.

To achieve this we'll define two custom CSS properties,--box-color and--width-subtractor.
The paint worklet
The worklet is an external JavaScript file (in this case we've called itboxbg.js) which defines a paintworklet.Using the worklet, we can access CSS properties (and custom properties) of elements:
registerPaint( "boxbg", class { static get contextOptions() { return { alpha: true }; } /* Retrieve any custom properties (or regular properties, such as 'height') defined for the element, and return them as an array. */ static get inputProperties() { return ["--box-color", "--width-subtractor"]; } paint(ctx, size, props) { /* ctx -> drawing context size -> paintSize: width and height props -> properties: get() method */ ctx.fillStyle = props.get("--box-color"); ctx.fillRect( 0, size.height / 3, size.width * 0.4 - props.get("--width-subtractor"), size.height * 0.6, ); } },);We used theinputProperties() method in theregisterPaint() class to get the values of two custom properties set on an element that hasboxbg applied to it and then used those within ourpaint() function. TheinputProperties() method can return all properties affecting the element, not just custom properties.
Using the paint worklet
HTML
<ul> <li>item 1</li> <li>item 2</li> <li>item 3</li> <li>item 4</li> <li>item 5</li> <li>item 6</li> <li>item 7</li> <li>item 8</li> <li>item 9</li> <li>item 10</li> <li>item N</li></ul>CSS
In our CSS, we define the--box-color and--width-subtractor custom properties.
body { font: 1.2em / 1.2 sans-serif;}li { background-image: paint(boxbg); --box-color: hsl(55 90% 60%);}li:nth-of-type(3n) { --box-color: hsl(155 90% 60%); --width-subtractor: 20;}li:nth-of-type(3n + 1) { --box-color: hsl(255 90% 60%); --width-subtractor: 40;}JavaScript
The setup and logic of the paint worklet is in the external script.To register the worklet, we need to calladdModule() from our main script:
CSS.paintWorklet.addModule( "https://mdn.github.io/houdini-examples/cssPaint/intro/worklets/boxbg.js",);In this example, the worklet is hosted athttps://mdn.github.io/, but your worklet may be a relative resource like so:
CSS.paintWorklet.addModule("boxbg.js");Result
While you can't play with the worklet's script, you can alter the custom property values in DevTools to change the colors and width of the background image.
Specifications
| Specification |
|---|
| CSS Painting API Level 1> # paintworkletglobalscope> |