Masonry Gallery
Pinterest-style variable-height gallery using pure CSS multi-column layout. Each image declares its own aspect ratio.
Preview
Source
tsx
"use client";
const IMAGES = [
{ src: "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&q=80&auto=format&fit=crop", alt: "Mountain lake aerial", ratio: "aspect-[3/4]" },
{ src: "https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?w=800&q=80&auto=format&fit=crop", alt: "Foggy alpine lake", ratio: "aspect-[4/3]" },
{ src: "https://images.unsplash.com/photo-1418065460487-3e41a6c84dc5?w=800&q=80&auto=format&fit=crop", alt: "Pink sunrise mountains", ratio: "aspect-square" },
{ src: "https://images.unsplash.com/photo-1499678329028-101435549a4e?w=800&q=80&auto=format&fit=crop", alt: "Stream and rocks", ratio: "aspect-[3/4]" },
{ src: "https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=800&q=80&auto=format&fit=crop", alt: "Misty green hills", ratio: "aspect-[4/3]" },
{ src: "https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=800&q=80&auto=format&fit=crop", alt: "Forest canopy", ratio: "aspect-square" },
{ src: "https://images.unsplash.com/photo-1470770841072-f978cf4d019e?w=800&q=80&auto=format&fit=crop", alt: "Lakeside cabin", ratio: "aspect-[4/5]" },
{ src: "https://images.unsplash.com/photo-1506744038136-46273834b3fb?w=800&q=80&auto=format&fit=crop", alt: "Mountain lake wide", ratio: "aspect-[4/3]" },
{ src: "https://images.unsplash.com/photo-1500964757637-c85e8a162699?w=800&q=80&auto=format&fit=crop", alt: "Snowcapped peaks", ratio: "aspect-[3/4]" },
{ src: "https://images.unsplash.com/photo-1458668383970-8ddd3927deed?w=800&q=80&auto=format&fit=crop", alt: "Mountain road", ratio: "aspect-[4/5]" },
];
export default function GalleryMasonry() {
return (
<section className="py-12 px-6 bg-background">
<div className="container mx-auto">
<div className="mb-8">
<h2 className="text-3xl md:text-4xl font-extrabold tracking-tight text-foreground">
Masonry gallery
</h2>
<p className="text-muted-foreground mt-1">
Variable heights with CSS columns — no JavaScript needed.
</p>
</div>
<div className="columns-2 md:columns-3 lg:columns-4 gap-4 [column-fill:_balance]">
{IMAGES.map((img, i) => (
<div
key={i}
className={`mb-4 overflow-hidden rounded-lg bg-muted break-inside-avoid ${img.ratio}`}
>
<img
src={img.src}
alt={img.alt}
loading="lazy"
className="w-full h-full object-cover hover:scale-105 transition-transform duration-500"
/>
</div>
))}
</div>
</div>
</section>
);
} Claude Code Instructions
CLI Install
npx innovations add masonryWhere to use it
Use when your images have mixed aspect ratios and a rigid grid would leave awkward whitespace.
In Astro (src/layouts/Layout.astro or a page):
import GalleryMasonry from '../components/innovations/galleries/masonry';
Customize: replace the IMAGES array. Each entry has {src, alt, ratio} where ratio is a Tailwind aspect-* class (aspect-square, aspect-[3/4], aspect-[4/3], aspect-[4/5], etc.). Mixing ratios is what makes masonry look good.