The Field Guide to CSS Grid Lanes
Skip to main content
The Field Guide to Grid Lanes
Masonry layouts in pure CSS. No JavaScript. No hacks. Just four lines of code.
Brought to you by the team behind WebKit and Safari.
This is an interactive demo of CSS Grid Lanes. Try it in a browser with support.
Or simply scroll down to learn more about Grid Lanes.
(It is easy to use Grid Lanes today with simple fallbacks. This example skips them for clarity.)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Resize width:
Layout direction
Waterfall
Brick
Responsive equal
Responsive alternating
Fixed + responsive
4 equal
Narrow–wide–narrow
Sidebar + main
4 auto
Short–tall–short
4 equal
Alternating
Flow tolerance
em<br>rem<br>lh<br>ch<br>px
Play tab order
Gap
em<br>rem<br>lh<br>ch<br>px
Copy
#Field Guide
Grid Lanes Basics
Fig. I
display: grid-lanes
Apply display: grid-lanes to a layout container. Then define columns or rows. The children pack into grid lanes automatically.
.container {<br>display: grid-lanes;<br>grid-template-columns: 1fr 1fr 1fr;
Fig. II
grid-template-columns
Waterfall
Defining columns creates a vertical waterfall. Tab order flows back and forth across the page. Each item is placed wherever puts it closest to the top. Additional items can be lazy-loaded at the bottom.
Fig. III
grid-template-rows
Brick
Defining rows creates a horizontal brick layout. Tab order flows up and down. Each item is placed wherever puts it closest to the inline start edge.
Options for Lane Definitions
fr unit
One fractional unit. Divides available space proportionally. 1fr 2fr 1fr gives the middle track twice the width.
grid-template-columns: 1fr 2fr 1fr;
Fixed lengths
Use any CSS unit to define a fixed size. The classics: px, em, rem. Newer ones: ch (a character’s width), lh (a line’s height). Plus powerful viewport and container units. Pick the unit that fits the job.
grid-template-columns: 12ch 1fr 20rem;
Percentage
The % unit resolves to percentage of the container’s size. It works — but fr units are usually a better fit, since they account for gap and % doesn’t. Plus you won’t have to worry about adding up to 100%.
grid-template-columns: 25% 75%;
auto
Sized by content. Stretches to fill remaining space when there’s room.
grid-template-columns: auto 1fr;
min-content & max-content
min-content
Most Narrow
max-content
Widest it can possibly be, no wrap
min-content makes a box the smallest it can be without overflow. max-content makes a box the biggest it can be, sized to its content.
grid-template-columns: max-content 1fr;<br>grid-template-columns: min-content 1fr;
fit-content()
300px ceiling
Box shrinks
With more content, box grows to limit declared and content wraps
Shrink-wrap with a ceiling. When there’s less content, fit-content behaves just like max-content. When there’s more content, it doesn’t grow beyond the declared size.
grid-template-columns: fit-content(300px) 1fr;
minmax()
200px
grows to 1fr
A flexible track sized between the declared minimum and maximum size. Using minmax(200px, 1fr) creates a track that’s never smaller than 200px, and grows to share any remaining space. When there’s more space, the browser automatically adds more tracks. Less space? Fewer tracks. No media or container queries needed!
grid-template-columns: minmax(200px, 1fr);
repeat()
Shorthand to repeat track patterns. These two lines are identical:
grid-template-columns: repeat(3, 1fr);<br>grid-template-columns: 1fr 1fr 1fr;
auto-fill vs auto-fit
auto-fill
auto-fit
Both automatically choose the number of tracks. auto-fill creates all tracks that will fit, even if empty. auto-fit creates tracks, but not more than there are items, so there are no empty tracks.
The Go-To
Want flexible equal-width columns, where additional columns appear and disappear automatically as space allows? Use this, adjusting the 120px length to your needs:
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));<br>Or use this to ensure that when the space available is extra narrow (less than 120px), the single column does not overflow:
grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr));
Options for Placement & Spacing
Fig. IV
flow-tolerance
flow-tolerance: 0
flow-tolerance: 4lh
Grid Lanes packs each item into whichever lane has the most empty space. When lanes are nearly equal and a one-pixel difference matters, the visual order gets scrambled for no good reason. Use flow-tolerance to declare “how close” matters. Anything less is considered a tie, and content flows in writing mode order. This better syncs visual order with tab order. The best value depends on your content’s sizes — experiment and see. Default is 1em.
flow-tolerance: 4lh;
Fig. V
gap
column-gap
row-gap
One value for uniform spacing. Two values for different row-gap and column-gap. Works just like CSS Grid.
gap: 1rem 2rem;
Fig. VI
Span across 2 lanes
Spanning Lanes
span 2
Stretch an item across...