What Is a Masonry Layout?
CSS masonry layouts--those elegant, Pinterest-style arrangements where items of varying heights pack together without gaps--have been a staple of modern web design for years. Yet achieving this effect natively in CSS has remained elusive, forcing developers to rely on JavaScript libraries or imperfect CSS workarounds.
Masonry layouts differ fundamentally from traditional grid layouts. In a standard CSS grid, rows and columns are rigidly defined, and items must fit within these predefined cells. If items have varying heights, you either accept gaps between them or stretch items to fill the space.
The masonry approach turns this constraint on its axis. One direction follows a strict grid, while the other becomes fluid--items simply flow into available space, rising to fill gaps as they appear. This creates that distinctive "waterfall" effect where shorter items tuck neatly beneath taller ones in adjacent columns, maximizing screen real estate and creating visually engaging compositions.
Common applications include:
- Image galleries with photos of varying aspect ratios
- Blog index pages where post excerpts span different lengths
- Product catalogs with item descriptions of varying lengths
- Portfolio showcases where project thumbnails naturally vary in size
The visual density that masonry creates works particularly well when content variety enhances rather than disrupts the experience. Photo galleries benefit from displaying full images without cropping, while content feeds display posts of all lengths in tight, gap-free arrangements that maintain visual interest throughout the scroll experience.
The CSS Working Group has finalized the specification for native masonry layout. Here's how the two main approaches work.
CSS Grid Masonry Keyword
Use grid-template-columns or grid-template-rows with the masonry keyword to create flexible layouts within the existing CSS Grid infrastructure.
CSS Grid Lanes
A dedicated display type (display: grid-lanes) that provides explicit masonry behavior with additional controls like flow-tolerance.
Item Spanning Support
Both approaches support spanning items across multiple lanes for featured content, headers, and visual hierarchy.
Flow Tolerance Control
Grid Lanes includes flow-tolerance to control when height differences affect lane assignment, improving layout stability.
1.masonry-grid {2 display: grid;3 /* Columns are the grid axis */4 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));5 /* Rows become the masonry axis */6 grid-template-rows: masonry;7 gap: 1rem;8}This example demonstrates the core syntax for native CSS masonry. The display: grid establishes a grid container, while grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)) creates responsive columns that fill the available width--each at least 250 pixels wide but stretching equally to fill space. The grid-template-rows: masonry declaration is where the magic happens: it tells the browser to treat rows as a masonry axis rather than fixed tracks. Items flow down columns rather than across rows, naturally packing together regardless of their individual heights.
The auto-fill keyword combined with minmax() ensures responsive behavior without media queries. As the container width changes, the browser calculates how many columns fit and creates them accordingly, adjusting column counts smoothly across breakpoints. The gap: 1rem property controls spacing between items, maintaining consistent gutters throughout the layout.
This approach represents the future of CSS-based layouts where native browser capabilities replace JavaScript dependencies.
CSS Grid Lanes: The Evolved Approach
WebKit has implemented display: grid-lanes as an alternative approach that provides more explicit control over masonry behavior. This syntax treats masonry as a dedicated display type rather than a grid configuration.
The grid-lanes value automatically determines the masonry axis based on which template property you specify. If you define columns with grid-template-columns, items flow vertically (column-based masonry). If you define rows with grid-template-rows, items flow horizontally (row-based masonry).
1.masonry-lanes {2 display: grid-lanes;3 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));4 gap: 1rem;5}6 7/* Optional: Control layout stability */8.masonry-stable {9 flow-tolerance: 2em;10}Understanding Flow Tolerance
The flow-tolerance property addresses a subtle but important layout behavior. When the browser places items, small differences in content height can cause items to shift between lanes in unexpected ways.
Tolerance accepts a length value (defaulting to 1em) that defines when height differences are considered significant enough to affect lane assignment:
- Lower tolerance (e.g.,
0.5em): Aggressive packing where even tiny height differences affect lane assignment, creating tighter layouts but potentially less stable content ordering - Default tolerance (
1em): Balanced behavior for most use cases, providing reasonable packing while maintaining moderate stability - Higher tolerance (e.g.,
2em): Stable layouts where items only shift lanes for substantially shorter content--useful when content order matters for accessibility or when items frequently change size
For image galleries and portfolios, lower tolerance works well since the visual presentation matters more than strict ordering. For blog indexes or content feeds where users expect logical reading order, higher tolerance prevents unexpected reordering that could confuse navigation. Dynamic content that changes height--perhaps due to user interactions or real-time updates--benefits from higher tolerance values that reduce reflow frequency and maintain consistent layouts.
Browser Support Status
Firefox
Behind flag (layout.css.grid-template-masonry-value.enabled)
Chrome 140+
Experimental (requires enabling CSS Masonry Layout flag)
Safari TP 234+
Full Grid Lanes support available
Item Spanning and Explicit Placement
Both masonry approaches support item spanning, allowing specific elements to occupy multiple tracks while the surrounding content adapts. This capability enables rich layouts where certain items stand out by stretching across lanes.
Items with explicit placement using line-based positioning are positioned first, and then the masonry algorithm places remaining items around them.
1/* Featured item spans 2 columns */2.featured-item {3 grid-column: span 2;4}5 6/* Hero content spans 4 columns */7.hero-content {8 grid-column: span 4;9}10 11/* Explicit positioning takes precedence */12.promoted {13 grid-column: 2 / 4;14}Fallback Strategies for Current Browsers
Until native masonry achieves broad support, CSS-only workarounds remain necessary for production websites. Each approach has distinct tradeoffs in performance, complexity, and visual fidelity.
CSS Column-Based Masonry
The multi-column layout module provides the simplest CSS-only masonry approximation:
.column-masonry {
column-count: 3;
column-gap: 1rem;
}
.column-masonry > * {
break-inside: avoid;
margin-bottom: 1rem;
}
Limitations: Items fill columns left-to-right within each column before moving to the next. All columns share identical sizing--there's no way to define different widths for different columns.
Flexbox Column Wrapping
.flex-masonry {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
height: 800px;
gap: 1rem;
}
Limitations: Requires a fixed or calculated height, and content ordering differs from visual order.
JavaScript Libraries
Established libraries like Masonry.js, Isotope, and Colcade provide full masonry implementations with features including animations, filtering, and dynamic content handling. However, JavaScript-based approaches require measuring DOM elements after initial render, calculating positions, and applying styles--all of which introduces performance overhead and can cause layout shifts. For static content without complex requirements, CSS-only fallbacks provide better performance with no JavaScript dependency.
When evaluating web development approaches, consider whether the additional JavaScript features are essential or whether CSS-only alternatives can achieve the desired outcome.
1/* Base fallback - works everywhere */2.masonry-container {3 column-count: 3;4 column-gap: 1rem;5}6 7.masonry-container > * {8 break-inside: avoid;9 margin-bottom: 1rem;10}11 12/* Native masonry for supporting browsers */13@supports (grid-template-rows: masonry) {14 .masonry-container {15 display: grid;16 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));17 grid-template-rows: masonry;18 column-gap: 1rem;19 row-gap: 1rem;20 }21 22 .masonry-container > * {23 margin-bottom: 0;24 }25}26 27/* Grid Lanes for Safari Technology Preview */28@supports (display: grid-lanes) {29 .masonry-container {30 display: grid-lanes;31 grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));32 gap: 1rem;33 flow-tolerance: 1em;34 }35}This progressive enhancement strategy delivers optimal experiences where possible while maintaining functionality everywhere. Users with the most capable browsers get the best layout behavior, while all users receive functional, accessible content. The base styles use multi-column layout--a widely supported CSS feature--ensuring acceptable masonry-like presentation even in browsers without any masonry support. Feature queries then layer in native implementations as browsers provide them.
Consider JavaScript libraries only when specific features demand them: complex filtering, animated reordering, or dynamic content streams that require real-time position recalculation. For static galleries, blogs, and product catalogs, CSS-only approaches provide superior performance with no JavaScript overhead. The goal is to achieve the visual benefits of masonry while minimizing complexity and maintaining fast, reliable page performance.
Practical Applications
Image Galleries and Portfolios
Photo galleries naturally benefit from masonry layouts because images arrive in varying aspect ratios--portraits, landscapes, squares--and forcing them into uniform grid cells either crops important content or leaves substantial gaps. Masonry preserves full images while tightly packing them, maximizing visual impact per pixel of screen space.
For portfolios featuring project thumbnails with varying descriptive text, masonry ensures captions and titles don't create awkward gaps beneath shorter items. Each card occupies only the space its content requires, with the layout adapting automatically as content changes. If you're building a portfolio or showcase site, masonry layouts provide an elegant solution for displaying varied content types.
Blog Indexes and Content Feeds
Blog archives often display post excerpts of varying lengths. Masonry creates compact, visually interesting indexes where posts of all lengths pack together naturally. The pattern works equally well for news sites, content aggregators, and feed-style displays where items have variable content length. Consider implementing spanning for featured or promoted content, allowing certain posts to stand out by occupying multiple lanes.
Product Catalogs
E-commerce product listings face similar challenges--some products have lengthy specifications while others fit in brief summaries. Masonry prevents the "staircase" effect where product cards create increasingly tall rows with large gaps. Instead, each product occupies minimal space while all products align in a clean, gap-free presentation. Featured products can span multiple columns using grid-column: span 2, creating visual hierarchy without disrupting the overall masonry flow.