Masonry Grid — Free HTML CSS JS Pinterest Snippet

Masonry Grid · Layouts · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

CSS columns: 3 creates masonry — browser fills columns top to bottom
break-inside: avoid prevents cards splitting across column boundaries
column-gap: 12px for column spacing; margin-bottom: 12px for row spacing
@media (max-width: 600px) { columns: 2 } — responsive without JS
Items rendered from JS data array — easy to filter, sort, and update
Each item has dynamic height for the natural masonry staggering effect
Cards with gradient header, emoji, title, author, and like count
Export as HTML, JSX, or Tailwind CSS
Mobile/Tablet/Desktop preview
Live editor — preview updates as you type

About this UI Snippet

Masonry Grid — CSS columns Property, break-inside: avoid & JS Rendering

Screenshot of the Masonry Grid snippet rendered live

A masonry grid displays items in a multi-column layout where items of different heights fill columns naturally from top to bottom — like a Pinterest or photo gallery layout, often wired to an image lightbox on click. This snippet implements masonry using the CSS columns property.

The CSS columns approach

.masonry { columns: 3; column-gap: 12px } is the entire masonry layout. The browser fills columns from top to bottom, stacking items by height. No JavaScript positioning is needed. @media (max-width: 600px) { .masonry { columns: 2 } } reduces to two columns on mobile.

break-inside: avoid

.item { break-inside: avoid } prevents a single card from splitting across two columns. Without this, tall cards can be split at the column boundary.

JS card rendering

Cards are rendered from a JS data array rather than static HTML. Each item has a title, subtitle, height, gradient, and like count. items.forEach(item => { const div = document.createElement('div'); ... container.appendChild(div) }) builds the grid dynamically. This makes it easy to filter, sort, and update items.

How CSS columns masonry works

CSS columns: 3 divides the container into 3 equal-width columns. Child elements fill top-to-bottom in columns — left column fills first, then centre, then right. break-inside: avoid prevents a single card from splitting across two columns. The browser handles variable-height items automatically — short cards and tall cards coexist naturally without JavaScript height calculation.

Advantages over JavaScript masonry libraries

Libraries like Masonry.js calculate absolute positions for each item using JavaScript, which requires a reflow after images load and creates complex dependencies. The CSS columns approach has zero JavaScript, works without images loading, recalculates on window resize automatically, and has no dependencies. The trade-off is that columns fill left-to-right before top-to-bottom — items do not arrange by insertion order across columns.

Adding new items dynamically

Since CSS columns is layout-based, adding new items via JavaScript (container.appendChild(newCard)) automatically triggers reflow and the masonry repositions. No JavaScript layout recalculation is needed. The grid updates instantly.

Responsive masonry

Change columns count responsively: @media (max-width: 900px) { .masonry { columns: 2; } } @media (max-width: 600px) { .masonry { columns: 1; } }. Or use the CSS columns auto-fill: columns: auto; column-width: 280px — the browser places as many 280px columns as fit the container width, similar to the responsive card grid but for a top-down fill pattern.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to guess why this masonry avoids Masonry.js entirely. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why the columns CSS property fills items top-to-bottom within a column before moving to the next column, and why that column-major fill order means items no longer read left-to-right in their original array order once the grid has more than one column. The same assistant can help optimize it, for instance asking whether building each card's HTML with repeated string concatenation into grid.innerHTML on every forEach iteration causes unnecessary reflows compared to building one HTML string and setting innerHTML once. It is also useful for extending the grid: ask it to add category filtering that re-renders only the filtered subset, swap the gradient placeholders for real lazy-loaded images without breaking break-inside: avoid, or add a load-more button that appends new items without rebuilding the whole grid. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "masonry grid" of variable-height cards in plain HTML, CSS, and JavaScript using the CSS columns property — no JavaScript-computed absolute positioning and no masonry library.

Requirements:
- A container styled with the CSS columns property set to a fixed count (e.g. 3), with a column-gap, and a narrower column count applied via a media query at a mobile breakpoint.
- Every card element must have break-inside: avoid so a single card is never visually split across two columns, and each card must carry its own bottom margin for consistent vertical spacing within a column.
- Render all cards from a single JavaScript array of objects, where each object defines at minimum a title, a subtitle, a distinct height for its visual header area, and an accent color, and build every card's markup from that data rather than hardcoding cards in the HTML.
- Each card must show a colored or gradient header area sized to its own height value, then a body section with the title, subtitle, an author avatar with initials colored from that item's accent color, and a like count.
- Hovering any card must apply a subtle scale-up transform and an elevated box-shadow via a CSS transition, without affecting the layout or position of neighboring cards in other columns.
- Demonstrate that adding or removing items from the underlying data array and re-rendering causes the masonry layout to reflow automatically with no manual position recalculation in JavaScript.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the snippetClick "Masonry Grid" in the sidebar. The preview shows cards of different heights filling three columns from top to bottom.
  2. 2
    Update card contentIn the JS panel, update the items array — change title, subtitle, height, gradient, and likes per item.
  3. 3
    Change column countUpdate columns: 3 in the CSS panel to 2 for a two-column layout or 4 for a denser grid.
  4. 4
    Add items with real imagesReplace the gradient div in each card with an <img> tag. The masonry layout handles any image height automatically.
  5. 5
    Add filteringFilter the items array and re-render: filteredItems = items.filter(i => i.category === sel). Re-build the grid from the filtered array.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Photo and image galleries
Display photos of varying heights in a masonry grid. The CSS columns approach handles any aspect ratio automatically.
Pinterest-style content boards
Show blog posts, designs, or products in a masonry grid where taller content fills the column without wasted space.
Portfolio and work showcase grids
Display portfolio pieces, case studies, or design work where each piece has a natural height based on its content.
Learn CSS columns vs CSS Grid for masonry
CSS columns fills top-to-bottom within each column. CSS Grid without masonry fills left-to-right in rows. Edit columns: 3 to see the difference.
Dynamic content feed grids
Render items from a data array as cards with variable heights. Adding or removing items automatically reflows the masonry layout.
Social media content boards
Display social media posts, tweets, or testimonials of varying lengths in a compact masonry arrangement.

Got questions?

Frequently Asked Questions

CSS columns: 3 tells the browser to divide the container into 3 equal-width columns. Children are placed top-to-bottom within each column before moving to the next. Items of different heights create the natural staggered masonry appearance.

break-inside: avoid on child elements prevents them from being split across column boundaries. Without it, a single card might have its top half in one column and its bottom half in the next.

CSS columns fills items top-to-bottom within columns (true masonry). CSS Grid fills items left-to-right in rows — you get equal row heights unless you use the experimental grid-template-rows: masonry property (limited browser support).

The CSS columns layout is column-ordered, not row-ordered, which makes drag-and-drop complex. For draggable masonry, use a JS masonry library (Masonry.js, react-masonry-css) that handles absolute positioning.

Yes. Click "JSX" for a React component. Map your items array to card components. The CSS columns layout applies identically in React. For more control, use the react-masonry-css library.

Filter the items array and re-render: filteredItems = items.filter(item => item.category === selectedCategory). Re-build the grid from the filtered array. The masonry layout automatically reflows.