Native Masonry Comes to CSS Grid

Masonry layout — the pattern where items flow one after another in the inline direction and then rise up to fill gaps left by shorter items — has long been a staple of visual-heavy sites. Pinterest made it famous, and David DeSandro's Masonry plugin has been the go-to JavaScript solution for years. But JavaScript-based layout is rarely performant, especially with the large item counts that often benefit from this pattern. Requests for a native CSS solution date back to early 2017.

Now there is a specification: CSS Grid Layout Level 3, which adds masonry as a grid behavior. The draft is accompanied by an early implementation in Firefox Nightly, so you can experiment with it right now. To get started, enable the layout.css.grid-template-masonry-value.enabled flag in about:config.

Why Not Just Use Existing CSS?

Two existing CSS features can approximate the look of masonry, but both fall short. Multi-column Layout (column-count and friends) creates a visually similar packed layout, but content runs down each column rather than across the row. If the first items in source order matter — like search results — the apparent top row is not showing the highest-priority items.

Grid with grid-auto-flow: dense can fill every gap, but the underlying structure remains a strict grid. Short items in one row cannot pull items from the following row up into the space above them. Masonry inherently requires breaking that rigid row structure.

An example layout from the Pintrest website
Pintrest

How Masonry Grid Works

Using masonry is straightforward: on one axis of your grid container, set the value masonry; the other axis keeps normal defined tracks. The axis with masonry becomes the masonry axis; the one with tracks is the grid axis. The example below creates a four-column grid — the grid axis — and allows the rows to pack masonry-style.

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: masonry;
}
A simple masonry layout
Our Pure CSS Masonry Layout

That minimal setup delivers a basic masonry layout. But because masonry is part of the Grid spec, the surrounding grid behaviors need definitions too.

Grid Axis Behaviors

The axis with defined tracks behaves exactly like a regular grid. You can size tracks, name lines, position items with line-based placement, and even span multiple tracks. Placed items are rendered first; masonry items then flow around them.

For instance, you can place an image with a caption between two named lines, box-start and box-end, and let the masonry items pack around that fixed element. You can also span items across tracks — for example, giving certain elements a class of landscape so they occupy two column tracks inside the masonry flow.

The masonry-auto-flow Property

Not yet in the Firefox implementation, masonry-auto-flow controls how items are placed along the grid axis. By default, items pack into the column with the most free space. Two extra values are defined:

  • next — places each item into the next available location on the grid axis, regardless of free space distribution.
  • ordered — ignores any definite placement and lays items out in order-modified document order, i.e., source order unless the order property changes it.

Alignment with align-tracks and justify-tracks

These two properties handle alignment specifically for the masonry axis. If masonry runs in the block direction, use align-tracks; for masonry in the inline direction, use justify-tracks. Their initial value is start, and they work in tandem with align-content and justify-content.

The values accepted match those of align-content. With a tall container whose align-tracks is set to end and default align-content: normal, the masonry tracks sit at the bottom of the container. Adding align-content: start shifts the whole block of tracks back to the top, but the ragged edges of the packing now appear at that top edge because each track is aligned to its end.

See the Pen Masonry align-tracks by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Masonry align-tracks by Rachel Andrew (@rachelandrew) on CodePen.
A simple masonry layout aligned to the end of the container
Aligning the masonry items to the end

Setting align-tracks: stretch stretches auto-sized items while still preserving the masonry effect; items with definite sizes are not distorted. These properties can also take multiple values, one per grid axis track — the first track could stretch, the second align to start, the third to end, and the fourth to center. However, that multiple-value support was not yet functional in Firefox at the time of writing. When fewer values are supplied than tracks, the last value applies to the rest; excess values are ignored.

Fallback Behavior

Because masonry shares structural DNA with auto-placement, unsupporting browsers gracefully fall back to regular grid auto-placement. The result will show gaps where items couldn't rise, but the layout remains presentable. You can also use feature queries to switch to multicol or any other pattern for browsers without masonry support.

@supports (grid-template-rows: masonry) {
  /* masonry code here */
}

If your layout depends on true masonry, you can feature-detect with CSS.supports and run your JavaScript masonry script only as a polyfill. Browsers with native support spare your users the script overhead.

Accessibility Considerations

Masonry creates another potential disconnection between visual order and document order. Content that appears higher on the page may not be earlier in the source, which is problematic for assistive technology and keyboard navigation. This is a long-standing issue with advanced CSS layout — the spec opens exciting possibilities while demanding increased care in application. Feedback on how to reconcile content order with display order remains an active conversation.

Test It and Contribute

The community is in an unusual position: a draft specification with a real browser implementation to probe. If masonry has a place in your projects, swap your JavaScript approach for the grid-based version and see where it breaks or falls short. Report issues to the CSS Working Group — experiments at this stage are how the spec gets refined and shipping browsers get better.