Masonry
Masonry layout creates a waterfall-style layout where items flow into columns based on their height, similar to Pinterest-style layouts.
⚠️ Experimental — uses CSS Grid Lanes. Safari 26.4+ ships it. Chrome, Edge, and Firefox still hide it behind a flag. See Browser Support.
Browser support
Section titled “Browser support”As of August 2026 (Can I Use):
- ✅ Safari 26.4+ / iOS Safari 26.4+ —
display: grid-lanesunflagged - ⚠️ Chrome / Edge 140+ — behind a flag (experimental
display: masonryis being replaced bygrid-lanes) - ⚠️ Firefox — behind a flag; many builds still use
grid-template-rows: masonry, notdisplay: grid-lanes
Fallback
Section titled “Fallback”Unsupported browsers get a regular CSS Grid: repeat(auto-fill, minmax(…)) with align-items: start. Items keep their height instead of stretching to the row. That is not a waterfall — short cards leave a gap beside taller ones.
Airframe does not fall back to CSS multi-column (columns / column-count). That packs by height, but reading and keyboard order go down the first column, then the next. Grid Lanes (and a normal grid) go left-to-right.
af-masonry also opts into older experimental syntax when present:
grid-template-rows: masonry(Firefox flag / Nightly)display: masonry(early Chromium flag)display: grid-lanes(Safari 26.4+, and others once they ship)
For a true waterfall in every browser, load a JavaScript layout library behind feature detection. Airframe stays CSS-only.
Class reference
Section titled “Class reference”| Class | Purpose | Column Width | Example |
|---|---|---|---|
af-masonry | Default masonry | 250px minimum | <div class="af-masonry"> |
af-masonry-sm | Small columns | 200px minimum | <div class="af-masonry-sm"> |
af-masonry-md | Medium columns | 250px minimum | <div class="af-masonry-md"> |
af-masonry-lg | Large columns | 300px minimum | <div class="af-masonry-lg"> |
af-masonry-xl | Extra large columns | 400px minimum | <div class="af-masonry-xl"> |
af-masonry-text | Text-optimized | 20ch minimum | <div class="af-masonry-text"> |
Basic masonry
Section titled “Basic masonry”<div class="af-masonry af-gap-lg">
<div class="af-card">Item 1</div>
<div class="af-card">Item 2</div>
<div class="af-card">Item 3</div>
<div class="af-card">Item 4</div>
</div>Card 1
Short content
Card 2
This card has more content to demonstrate how masonry layouts work.
Card 3
Medium content
Card 4
Another short card
Masonry variants
Section titled “Masonry variants”<div class="af-masonry-sm">Small columns (200px min)</div>
<div class="af-masonry">Default columns (250px min)</div>
<div class="af-masonry-lg">Large columns (300px min)</div>
<div class="af-masonry-xl">Extra large columns (400px min)</div>
<div class="af-masonry-text">Text-optimized (20ch min)</div>Card 1
Short content
Card 2
This card has more content to demonstrate how masonry layouts work. Items flow into columns based on their height.
Card 3
Medium content here
Card 4
Another short card
When to use
Section titled “When to use”- Photo galleries with varying image heights
- Card layouts with different content lengths
- Article teasers or blog post previews
- Product listings with varying descriptions
Polyfill for production
Section titled “Polyfill for production”Airframe does not ship a masonry JavaScript polyfill. If you need a waterfall in Chrome and Firefox today, feature-detect and load a library:
const masonrySupported =
CSS.supports('display', 'grid-lanes') ||
CSS.supports('display', 'masonry') ||
CSS.supports('grid-template-rows', 'masonry');
if (!masonrySupported) {
import('masonry-layout').then(({ default: Masonry }) => {
document.querySelectorAll('[class*="af-masonry"]').forEach((grid) => {
new Masonry(grid, {
itemSelector: ':scope > *',
percentPosition: true,
gutter: 16,
});
});
});
}That selector covers af-masonry, af-masonry-sm, and the other width variants. Tune gutter to match your af-gap-*.
See Browser Support for more details.