CSS Houdini Overview
CSS Houdini is not a single feature but a collection of low-level APIs that expose parts of the browser's CSS rendering engine directly to JavaScript. Historically, if CSS couldn't do something — a custom paint effect, a custom layout algorithm — the only option was to abandon CSS for that part and reimplement the whole visual behavior in JavaScript, usually by measuring elements and pushing around absolutely-positioned divs. Houdini's philosophy is narrower and more surgical: if you can't do it in CSS, write a small, focused worklet that plugs into the specific stage of the rendering pipeline you need, and let the browser continue handling everything else — layout, compositing, painting — exactly as it normally would.
The Houdini family of APIs
API | What it exposes | Status |
|---|---|---|
Properties and Values API | Registering typed, animatable custom properties — this is what | Broadly available — the Houdini API most developers actually touch |
Paint API | A | Available in Chromium-based browsers; check other engines |
Typed OM (Typed Object Model) | Reading/writing CSS values as structured typed objects from JS instead of parsing strings — see CSS Typed Object Model | Partial — core pieces are available, the full spec is still evolving |
Layout API | A | Experimental / limited — not broadly shipped |
Animation Worklet | High-performance, off-main-thread scroll- and gesture-driven animations | Mostly superseded in practice by native scroll-driven animations and the View Transitions API |
Why @property matters more day-to-day
@property --my-value { ... } is Houdini — you're registering a property with the same underlying mechanism a worklet-based feature would use — but it reads and feels like ordinary CSS./* This is CSS syntax, but it's Houdini under the hood — it
registers a typed custom property via the Properties and
Values API, without ever touching JavaScript. */
@property --highlight-angle {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}The worklet pattern, in general
The other Houdini APIs follow a shared shape: register a small JavaScript class in a worklet module, then reference it by name from CSS. The Paint API page walks through this in detail with a concrete example.
// A minimal illustration of the general worklet shape —
// register a class with a defined "hook" method, then use
// it from CSS by the name it was registered under.
CSS.paintWorklet.addModule('my-worklet.js')
// inside my-worklet.js:
class MyPainter {
paint(ctx, size, properties) {
// draw using Canvas-like APIs
}
}
registerPaint('my-painter', MyPainter)@property than to write a Paint API worklet or a Layout API worklet — but knowing the family exists explains where @property actually comes from, and gives you a mental map for what to search for if you ever hit a wall that plain CSS genuinely can't clear.