Pattern
Visual rhythm
A short card opens the composition.
Build masonry-like layouts with native CSS: switch between waterfall and brick, combine lane patterns, tune flow tolerance, and test progressive enhancement in browsers without support.
Use Tab to verify that focus preserves DOM order even when visual placement changes.
<ul class="lanes">
<li id="lane-1" class="lane-card">
<article>
<p class="eyebrow">Pattern</p>
<h2>Visual rhythm</h2>
<p>A short card opens the composition.</p>
<a href="#lane-1" aria-label="Open card: Visual rhythm">01</a>
</article>
</li>
<li id="lane-2" class="lane-card">
<article>
<p class="eyebrow">CSS</p>
<h2>No JavaScript</h2>
<p>Items are distributed across lanes and packed toward the container start natively.</p>
<a href="#lane-2" aria-label="Open card: No JavaScript">02</a>
</article>
</li>
<li id="lane-3" class="lane-card">
<article>
<p class="eyebrow">Layout</p>
<h2>Flexible tracks</h2>
<p>Combine repeat(), minmax(), and fr units.</p>
<a href="#lane-3" aria-label="Open card: Flexible tracks">03</a>
</article>
</li>
<li id="lane-4" class="lane-card">
<article>
<p class="eyebrow">Order</p>
<h2>The DOM stays intact</h2>
<p>Reading and focus follow source order even when visual placement changes.</p>
<a href="#lane-4" aria-label="Open card: The DOM stays intact">04</a>
</article>
</li>
<li id="lane-5" class="lane-card">
<article>
<p class="eyebrow">Detail</p>
<h2>Tolerance</h2>
<p>flow-tolerance decides when two positions should be treated as tied.</p>
<a href="#lane-5" aria-label="Open card: Tolerance">05</a>
</article>
</li>
<li id="lane-6" class="lane-card">
<article>
<p class="eyebrow">Responsive</p>
<h2>No media queries</h2>
<p>auto-fit can add or remove lanes as space changes.</p>
<a href="#lane-6" aria-label="Open card: No media queries">06</a>
</article>
</li>
<li id="lane-7" class="lane-card">
<article>
<p class="eyebrow">Axes</p>
<h2>Waterfall or brick</h2>
<p>Define columns or rows to switch direction.</p>
<a href="#lane-7" aria-label="Open card: Waterfall or brick">07</a>
</article>
</li>
<li id="lane-8" class="lane-card">
<article>
<p class="eyebrow">Content</p>
<h2>Different sizes</h2>
<p>Text, images, and components can keep their intrinsic dimensions.</p>
<a href="#lane-8" aria-label="Open card: Different sizes">08</a>
</article>
</li>
<li id="lane-9" class="lane-card">
<article>
<p class="eyebrow">Grid</p>
<h2>Spans and placement</h2>
<p>Every item can span several lanes or start on a specific line.</p>
<a href="#lane-9" aria-label="Open card: Spans and placement">09</a>
</article>
</li>
</ul><ul class="columns-4 [column-gap:16px] supports-[display:grid-lanes]:columns-auto supports-[display:grid-lanes]:[display:grid-lanes] supports-[display:grid-lanes]:[grid-template-columns:repeat(auto-fit,_minmax(min(12rem,_100%),_1fr))] supports-[display:grid-lanes]:gap-y-[16px] supports-[display:grid-lanes]:gap-x-[16px]">
<li id="lane-1" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Pattern</p>
<h2>Visual rhythm</h2>
<p>A short card opens the composition.</p>
<a href="#lane-1" aria-label="Open card: Visual rhythm">01</a>
</article>
</li>
<li id="lane-2" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">CSS</p>
<h2>No JavaScript</h2>
<p>Items are distributed across lanes and packed toward the container start natively.</p>
<a href="#lane-2" aria-label="Open card: No JavaScript">02</a>
</article>
</li>
<li id="lane-3" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Layout</p>
<h2>Flexible tracks</h2>
<p>Combine repeat(), minmax(), and fr units.</p>
<a href="#lane-3" aria-label="Open card: Flexible tracks">03</a>
</article>
</li>
<li id="lane-4" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Order</p>
<h2>The DOM stays intact</h2>
<p>Reading and focus follow source order even when visual placement changes.</p>
<a href="#lane-4" aria-label="Open card: The DOM stays intact">04</a>
</article>
</li>
<li id="lane-5" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Detail</p>
<h2>Tolerance</h2>
<p>flow-tolerance decides when two positions should be treated as tied.</p>
<a href="#lane-5" aria-label="Open card: Tolerance">05</a>
</article>
</li>
<li id="lane-6" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Responsive</p>
<h2>No media queries</h2>
<p>auto-fit can add or remove lanes as space changes.</p>
<a href="#lane-6" aria-label="Open card: No media queries">06</a>
</article>
</li>
<li id="lane-7" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Axes</p>
<h2>Waterfall or brick</h2>
<p>Define columns or rows to switch direction.</p>
<a href="#lane-7" aria-label="Open card: Waterfall or brick">07</a>
</article>
</li>
<li id="lane-8" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Content</p>
<h2>Different sizes</h2>
<p>Text, images, and components can keep their intrinsic dimensions.</p>
<a href="#lane-8" aria-label="Open card: Different sizes">08</a>
</article>
</li>
<li id="lane-9" class="inline-block w-full align-top mb-[16px] supports-[display:grid-lanes]:block supports-[display:grid-lanes]:mb-0 break-inside-avoid rounded-2xl border border-slate-300 bg-slate-50 p-4 text-slate-900">
<article>
<p class="eyebrow">Grid</p>
<h2>Spans and placement</h2>
<p>Every item can span several lanes or start on a specific line.</p>
<a href="#lane-9" aria-label="Open card: Spans and placement">09</a>
</article>
</li>
</ul>@supports (display: grid-lanes) {
.lanes {
display: grid-lanes;
grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
gap: 16px;
}
}
.lanes {
margin: 0;
padding: 0;
list-style: none;
}
.lane-card {
padding: 1rem;
border: 1px solid #cbd5e1;
border-radius: 1rem;
background: #f8fafc;
color: #0f172a;
}
@supports not (display: grid-lanes) {
.lanes {
columns: 4;
column-gap: 16px;
}
.lane-card {
display: inline-block;
inline-size: 100%;
break-inside: avoid;
margin-block-end: 16px;
vertical-align: top;
}
}.lanes {
@supports (display: grid-lanes) {
display: grid-lanes;
grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
gap: 16px;
}
margin: 0;
padding: 0;
list-style: none;
> .lane-card {
padding: 1rem;
border: 1px solid #cbd5e1;
border-radius: 1rem;
background: #f8fafc;
color: #0f172a;
}
@supports not (display: grid-lanes) {
columns: 4;
column-gap: 16px;
> .lane-card {
display: inline-block;
inline-size: 100%;
break-inside: avoid;
margin-block-end: 16px;
vertical-align: top;
}
}
}