# CSS Painting API (Houdini)

The CSS Painting API is part of the CSS Houdini project. It allows developers to write JavaScript functions that can draw directly into an element's background, border, or content image. Essentially, it lets you create custom CSS images programmatically.

## 1. The Concept

Traditionally, if you wanted a complex background pattern that CSS gradients couldn't handle, you had to use an image (PNG/SVG) or a `<canvas>` element. The CSS Painting API allows you to define a "painter" in JavaScript that the browser calls whenever it needs to paint an element.

This runs in a **Worklet**, which is a lightweight version of a Web Worker.

## 2. Defining a Paint Worklet

You create a separate JavaScript file (e.g., `checkerboard.js`) and define a class with a `paint()` method.

```javascript
// checkerboard.js
class CheckerboardPainter {
  // Define input properties (CSS variables) we want to access
  static get inputProperties() {
    return ['--checker-size', '--checker-color'];
  }

  paint(ctx, geometry, properties) {
    // ctx: Similar to Canvas 2D context (subset)
    // geometry: { width, height } of the area
    // properties: Map of input properties
    
    const size = parseInt(properties.get('--checker-size').toString()) || 20;
    const color = properties.get('--checker-color').toString() || 'black';
    
    ctx.fillStyle = color;
    
    for (let y = 0; y < geometry.height / size; y++) {
      for (let x = 0; x < geometry.width / size; x++) {
        if ((x + y) % 2 === 0) {
          ctx.fillRect(x * size, y * size, size, size);
        }
      }
    }
  }
}

// Register the painter
registerPaint('checkerboard', CheckerboardPainter);
```

## 3. Registering the Worklet

In your main JavaScript file, you load the worklet module.

```javascript
// main.js
if ('paintWorklet' in CSS) {
  CSS.paintWorklet.addModule('checkerboard.js');
}
```

## 4. Using it in CSS

Once registered, you can use the `paint()` function in CSS wherever an image is expected (like `background-image` or `border-image`).

```css
.my-element {
  width: 300px;
  height: 300px;
  
  /* Set custom properties */
  --checker-size: 30;
  --checker-color: red;
  
  /* Use the painter */
  background-image: paint(checkerboard);
}
```

## 5. Advantages

*   **Performance:** Runs off the main thread (in the worklet).
*   **Scalability:** Like SVG, it's drawn programmatically, so it looks crisp at any resolution.
*   **Responsiveness:** It automatically redraws when the element resizes or when input properties (CSS variables) change.
*   **Small Size:** Code is usually much smaller than an equivalent image file.

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/canvas-api]]
[[programming/javascript/vanilla/web-workers]]