Clean • Professional
CSS Houdini is a set of low-level browser APIs that let developers directly control the CSS rendering engine. It allows custom layouts, styles, animations, and properties without heavy JavaScript.
The Paint API allows you to draw custom graphics directly in CSS using a JavaScript paint worklet, reducing reliance on JavaScript for styling.
<div class="box">Custom Gradient Border</div>
<script>
CSS.paintWorklet.addModule('gradient-border.js');
</script>
.box {
width: 200px;
height: 100px;
border: 10px solid;
border-image: paint(gradient-border) 10;
}
gradient-border.js)registerPaint('gradient-border', class {
paint(ctx, size) {
const gradient = ctx.createLinearGradient(0, 0, size.width, size.height);
gradient.addColorStop(0, 'blue');
gradient.addColorStop(1, 'purple');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, size.width, size.height);
}
});
Define custom layout algorithms like masonry, circular, or grid variations.
Example:
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
.container {
display: layout(masonry); /* Requires a custom layout worklet */
gap: 10px;
}
.item {
background-color: lightblue;
padding: 20px;
border-radius: 8px;
text-align: center;
}
Enables high-performance animations tied to scroll, timeline, or custom triggers.
Example:
registerAnimator('scroll', class {
animate(context, timeline) {
// Scroll-driven animation logic
const progress = timeline.currentTime / timeline.duration;
context.element.style.transform = `translateX(${progress * 100}px)`;
}
});
Allows custom CSS properties with type validation and dynamic behavior.
Example:
CSS.registerProperty({
name: '--custom-radius',
syntax: '<length>',
inherits: false,
initialValue: '10px'
});
Animated Example
Animate a custom property for a spinner element:
<div class="spinner"></div>
/* Register a custom property for rotation */
@property --spin-angle {
syntax: '<angle>';
inherits: false;
initialValue: 0deg;
}
/* Spinner element using the custom property */
.spinner {
--spin-angle: 0deg;
width: 100px;
height: 100px;
border: 8px solid lightgray;
border-top-color: steelblue;
border-radius: 50%;
animation: spin 2s linear infinite;
transform: rotate(var(--spin-angle));
}
/* Animate the custom property */
@keyframes spin {
to { --spin-angle: 360deg; }
}