Demos
Each example is a live <pattern-grid> element styled with author CSS. View source on this page to see exactly how each one is built.
1. Hello rainbow
A 64-cell grid with HSL hues driven by sibling-index() and sibling-count().
<pattern-grid cells="8x8"></pattern-grid>
<style>
pattern-grid {
display: grid;
grid-template-columns: repeat(var(--pg-cols), 1fr);
}
pattern-grid > i {
aspect-ratio: 1;
background: hsl(
calc(sibling-index() / sibling-count() * 360)
70% 50%
);
}
</style>
2. Concentric rotation
32 cells stacked in the same grid cell, each smaller and more rotated than the last. No JS animation โ pure CSS.
<pattern-grid cells="32"></pattern-grid>
<style>
pattern-grid {
display: grid;
place-items: center;
aspect-ratio: 1;
}
pattern-grid > i {
grid-area: 1 / 1;
width: calc(100% * sibling-index() / sibling-count());
aspect-ratio: 1;
border: 1px solid hsl(calc(sibling-index() * 11) 70% 60%);
border-radius: 30%;
transform: rotate(calc(sibling-index() * 5deg));
}
</style>
3. 2D coordinates from the sibling shim
With shim="sibling", the component sets typed integer custom properties (--i per cell, --n on the host). That lets mod() and floor() recover (x, y) coordinates reliably. Color shifts on a diagonal.
<pattern-grid cells="16x16" shim="sibling"></pattern-grid>
<style>
/* Register so CSS math types numerically */
@property --idx { syntax: '<integer>'; inherits: false; initial-value: 0; }
@property --x { syntax: '<integer>'; inherits: false; initial-value: 0; }
@property --y { syntax: '<integer>'; inherits: false; initial-value: 0; }
pattern-grid > i {
--idx: calc(var(--i) - 1);
--x: mod(var(--idx), var(--pg-cols));
--y: calc((var(--idx) - var(--x)) / var(--pg-cols));
background: hsl(
calc((var(--x) + var(--y)) * 8) 70% 50%
);
}
</style>
4. Template cells
Provide a <template> child and each cell becomes a clone of its content. Buttons here, but it can be anything โ links, images, custom elements.
<pattern-grid cells="4x4">
<template>
<button class="tile">+</button>
</template>
</pattern-grid>
5. Hand-authored cells (no JS required)
When the child count already matches cols ร rows, JS leaves them alone. This block also renders correctly with JavaScript disabled.
6. Vanilla Breeze tokens
Because cells live in the light DOM, any inherited custom properties cascade in. Here the design tokens come from a parent.
/* VB tokens cascade into light DOM cells */
pattern-grid > i {
background: hsl(
calc(sibling-index() / sibling-count() * 360)
var(--vb-color-saturation)
var(--vb-color-lightness)
);
border-radius: var(--vb-radius-sm);
}
7. Sibling shim โ works in Firefox today
Setting shim="sibling" writes --i on each cell and --n on the host, so author CSS works in browsers that don't yet ship sibling-index(). Author CSS can prefer the native function with a fallback.
With shim="sibling":
Without shim:
<pattern-grid cells="36" shim="sibling"></pattern-grid>
<style>
pattern-grid > i {
/* prefer shim, fall back to native */
--idx: var(--i, sibling-index());
background: hsl(calc(var(--idx) * 10) 70% 50%);
}
</style>
8. Seeded randomness
Wrap a <pattern-grid> in <seed-context> and the component writes --rand-0...--rand-7 floats and matching --randi-0...--randi-7 integers on each cell, derived from a seeded mulberry32 PRNG. Same seed reproduces the same randoms across reloads.
<seed-context seed="hello">
<pattern-grid cells="8x8"></pattern-grid>
</seed-context>
<style>
pattern-grid > i {
background: hsl(
calc(var(--rand-0) * 360deg) 70% 50%
);
}
</style>
9. API explorer
Drag the sliders to mutate cols and rows attributes live. The component listens to attribute changes and regenerates cells.
10. The render event
Every regeneration fires a pattern-grid:render event with the new { cols, rows, total } in its detail. Useful for tying side effects to grid changes.
document.querySelector('pattern-grid')
.addEventListener('pattern-grid:render', (e) => {
console.log('Regenerated:', e.detail);
// e.detail === { cols: 8, rows: 8, total: 64 }
});