Masonry Grid

Gallery layout with varied item heights packed together.

html

<div class="masonry" style="columns:3;column-gap:8px;">
  <div class="masonry__tile" style="height:120px;margin-bottom:8px;border-radius:10px;border-top:3px solid #A8E6C1;"><svg viewBox="0 0 200 120" width="100%" height="100%" aria-hidden="true"><rect width="200" height="120" fill="#BFD9F2"/></svg></div>
  <div class="masonry__tile" style="height:180px;margin-bottom:8px;border-radius:10px;"><svg viewBox="0 0 200 180" width="100%" height="100%" aria-hidden="true"><rect width="200" height="180" fill="#D9C8F0"/></svg></div>
  <div class="masonry__tile" style="height:90px;margin-bottom:8px;border-radius:10px;border-top:3px solid #A8E6C1;"><svg viewBox="0 0 200 90" width="100%" height="100%" aria-hidden="true"><rect width="200" height="90" fill="#F5C2E0"/></svg></div>
  <div class="masonry__tile" style="height:150px;margin-bottom:8px;border-radius:10px;"><svg viewBox="0 0 200 150" width="100%" height="100%" aria-hidden="true"><rect width="200" height="150" fill="#A8E6C1"/></svg></div>
  <div class="masonry__tile" style="height:110px;margin-bottom:8px;border-radius:10px;"><svg viewBox="0 0 200 110" width="100%" height="100%" aria-hidden="true"><rect width="200" height="110" fill="#E8A02033"/></svg></div>
  <div class="masonry__tile" style="height:160px;margin-bottom:8px;border-radius:10px;border-top:3px solid #A8E6C1;"><svg viewBox="0 0 200 160" width="100%" height="100%" aria-hidden="true"><rect width="200" height="160" fill="#BFD9F2"/></svg></div>
</div>
<style>
.masonry { max-width: 380px; }
.masonry__tile { break-inside: avoid; overflow: hidden; background: #FAF7F2; border: 1px solid #24143022; }
.masonry__tile svg { display: block; }
</style>

tailwind

<div class="masonry-tw max-w-[380px]" style="columns:3;column-gap:8px;">
  <div class="masonry-tw__tile break-inside-avoid overflow-hidden bg-[#FAF7F2] border border-[#24143022]" style="height:120px;margin-bottom:8px;border-radius:10px;border-top:3px solid #A8E6C1;"><svg viewBox="0 0 200 120" width="100%" height="100%" aria-hidden="true"><rect width="200" height="120" fill="#BFD9F2"/></svg></div>
  <div class="masonry-tw__tile break-inside-avoid overflow-hidden bg-[#FAF7F2] border border-[#24143022]" style="height:180px;margin-bottom:8px;border-radius:10px;"><svg viewBox="0 0 200 180" width="100%" height="100%" aria-hidden="true"><rect width="200" height="180" fill="#D9C8F0"/></svg></div>
  <div class="masonry-tw__tile break-inside-avoid overflow-hidden bg-[#FAF7F2] border border-[#24143022]" style="height:90px;margin-bottom:8px;border-radius:10px;border-top:3px solid #A8E6C1;"><svg viewBox="0 0 200 90" width="100%" height="100%" aria-hidden="true"><rect width="200" height="90" fill="#F5C2E0"/></svg></div>
  <div class="masonry-tw__tile break-inside-avoid overflow-hidden bg-[#FAF7F2] border border-[#24143022]" style="height:150px;margin-bottom:8px;border-radius:10px;"><svg viewBox="0 0 200 150" width="100%" height="100%" aria-hidden="true"><rect width="200" height="150" fill="#A8E6C1"/></svg></div>
  <div class="masonry-tw__tile break-inside-avoid overflow-hidden bg-[#FAF7F2] border border-[#24143022]" style="height:110px;margin-bottom:8px;border-radius:10px;"><svg viewBox="0 0 200 110" width="100%" height="100%" aria-hidden="true"><rect width="200" height="110" fill="#E8A02033"/></svg></div>
  <div class="masonry-tw__tile break-inside-avoid overflow-hidden bg-[#FAF7F2] border border-[#24143022]" style="height:160px;margin-bottom:8px;border-radius:10px;border-top:3px solid #A8E6C1;"><svg viewBox="0 0 200 160" width="100%" height="100%" aria-hidden="true"><rect width="200" height="160" fill="#BFD9F2"/></svg></div>
</div>

react

export function MasonryGrid({
  columns = 3,
  gap = 8,
  radius = 10,
  accent = "#A8E6C1",
}) {
  const tiles = [
    { h: 120, fill: "#BFD9F2", accented: true },
    { h: 180, fill: "#D9C8F0", accented: false },
    { h: 90, fill: "#F5C2E0", accented: true },
    { h: 150, fill: "#A8E6C1", accented: false },
    { h: 110, fill: "#E8A02033", accented: false },
    { h: 160, fill: "#BFD9F2", accented: true },
  ];
  return (
    <div style={{ maxWidth: 380, columns, columnGap: gap }}>
      {tiles.map((t, i) => (
        <div key={i} style={{ breakInside: "avoid", overflow: "hidden", background: "#FAF7F2",
          border: "1px solid #24143022", height: t.h, marginBottom: gap, borderRadius: radius,
          borderTop: t.accented ? `3px solid ${accent}` : undefined }}>
          <svg viewBox={`0 0 200 ${t.h}`} width="100%" height="100%" aria-hidden="true">
            <rect width="200" height={t.h} fill={t.fill} />
          </svg>
        </div>
      ))}
    </div>
  );
}