This guide explains how CSS Grid’s lane-based alignment (grid lines and tracks) fits into masonry-style layouts, letting you create Pinterest-like columns without heavy JavaScript. You’ll learn the core concepts, then apply them step-by-step to build a responsive masonry grid that uses CSS Grid’s native capabilities.
What You’ll Need
- A text editor (VS Code, Sublime, etc.)
- A modern browser that supports CSS Grid (Chrome, Firefox, Safari, Edge)
- Basic understanding of HTML and CSS
- Optional: a few images or content blocks to test with
Step-by-Step
- Understand the core concept: CSS Grid normally creates rows and columns that align tightly. Masonry layouts break that alignment vertically—items in one column can be taller or shorter than those next to them. The key is to let each column behave like its own stacking context. CSS Grid does not have a native
masonryvalue (except experimental support in some browsers), so we’ll emulate it by defining columns and letting items flow naturally. - Set up your HTML structure: Create a container
<div class="masonry">and place your items inside. Each item should be a direct child, like<div class="item">...</div>. For this example, we’ll use images with varying heights. - Define the grid container: In your CSS, set
display: grid;on the container. Then define the columns usinggrid-template-columns. For a masonry effect, use a fixed number of columns withrepeat(), or useauto-fillwith a minimum width for responsiveness. Example:grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));This creates as many columns as fit, each at least 250px wide. - Set the row behavior: To allow items to stack vertically without forcing equal heights, use
grid-auto-rows: 10px;or a small value like8px. This sets the height of implicit rows. Then, on each item, setgrid-row: span N;where N is the number of rows the item should span. For example, an image that is 300px tall might span 30 rows if each row is 10px. This creates the staggered effect. - Apply the span to each item: You can either manually set
grid-row: span 30;on each item, or use a class like.talland.shortto vary heights. For a dynamic approach, you could use JavaScript to calculate the span based on the content height, but for a pure CSS solution, you’ll set fixed spans. Example:.item { grid-row: span 20; } .item.tall { grid-row: span 30; } - Add the gap: Use
gap: 10px;(orgrid-gapfor older browsers) to add space between items. This prevents them from touching and makes the layout readable. - Make it responsive: The
auto-fillandminmax()approach already makes columns responsive. For finer control, you can use media queries to change the column count. For example, on mobile you might want 1 or 2 columns, on tablet 3, and on desktop 4. Adjust thegrid-template-columnsaccordingly. - Test and refine: Open your page in the browser and inspect the layout. Adjust the row height and span values until the visual rhythm looks good. Remember that the row height acts as a base unit—smaller values give more control but require larger spans.
Common Mistakes
- Using
grid-auto-rows: auto;—this makes rows size to content, which defeats the masonry effect because rows will align again. - Forgetting to set
grid-rowon items—without spans, items will just fill the grid in normal order, giving a regular grid layout. - Setting
grid-auto-flow: row;(the default)—this places items row by row, which can cause gaps. For masonry, you wantgrid-auto-flow: row dense;to backfill gaps, or usecolumnflow (see Tips). - Using fixed pixel heights for items—if your images have varying natural heights, the spans might not match, causing misalignment. Use a consistent base unit.
Tips
- Use
grid-auto-flow: column dense;for a different masonry feel: This creates columns that fill vertically first, then move to the next column. It’s often better for masonry because it avoids horizontal gaps. Setgrid-template-rows: repeat(auto-fill, minmax(10px, 1fr));and then let items span columns instead of rows. - Combine with
object-fit: cover;on images to ensure they fill their grid area nicely without distortion. - Use CSS variables for row height and spans to make adjustments easier. For example:
:root { --row-height: 10px; }and thengrid-auto-rows: var(--row-height);. - For dynamic content, consider a small JavaScript helper that calculates the span based on the element’s offsetHeight. This gives a true masonry effect without manual spans.
- Always test in multiple browsers—CSS Grid is well-supported, but the
masonryproperty is still experimental. Stick to the span technique for maximum compatibility.
Troubleshooting
- Items are not overlapping or staggering: Check that
grid-auto-rowsis set to a small value (like 10px) and that items havegrid-row: span N. If you’re usinggrid-auto-flow: row;, try switching torow denseto fill gaps. - Gaps appear between items: This usually happens when the total span of items in a row doesn’t add up to the full width. Use
denseflow to backfill, or adjust your spans to be more flexible. - Items overflow their grid area: If an item’s content is taller than the span, it will overflow. Increase the span value or ensure the content has a max-height. For images, use
object-fit: cover;and a fixed height on the item. - The layout looks like a regular grid: Make sure you haven’t set
grid-template-rowsto a fixed value likerepeat(3, 200px). That forces equal rows. Useautorows with a small base. - Columns are not responsive: If you’re using
auto-fill, ensure the container has a width. If you’re using media queries, check that they are placed after the base styles.
Frequently Asked Questions
Can I use CSS Grid’s native masonry property?
As of now, the masonry value for grid-template-columns or grid-template-rows is only supported in Firefox (behind a flag) and Safari (as of 2023). For production, stick to the span technique described here.
Why do I need to set a small row height?
Setting a small row height (like 10px) gives you fine-grained control over how many rows each item spans. If you set it to 100px, you can only span in multiples of 100, which limits your layout flexibility.
What’s the difference between row dense and column dense?
row dense fills gaps by placing items in the next available row, which can leave vertical gaps. column dense fills gaps by moving to the next column, which is often better for masonry because it keeps columns tight.
Can I use this technique with dynamic content?
Yes, but you’ll need JavaScript to measure the height of each item and set the appropriate span. A simple script can loop through items and set grid-row: span Math.ceil(item.offsetHeight / rowHeight).
Is this better than using flexbox or a JavaScript library?
CSS Grid with spans is lightweight and works well for most masonry layouts. Flexbox can’t do masonry without extra wrappers. JavaScript libraries like Masonry.js offer more features but add overhead. For simple grids, CSS is sufficient.
How do I make the masonry layout work in older browsers?
If you need to support Internet Explorer, you’ll need a fallback like a flexbox-based layout or a JavaScript solution. Modern browsers (Chrome, Firefox, Safari, Edge) all support CSS Grid.
Related
General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.
More in this bed
- Photonic Inference vs GPU Inference: Key Differences16,384.00 µs
- Android Low Storage Survival Tips That Actually Work
- How to Password Protect PDFs on iPhone
- iPhone Force Restart Not Working? Fixes
- Add or Remove Keyboard Layout in Windows 10
- Razer Barracuda V2 Pro Dongle: Store & Find