Skip to main content

Masonry

A measured, accessible masonry layout for cards and media with uneven heights.

Package@g4rcez/componentsSectionDisplay Components

Examples

Basic Masonry

Render cards with uneven heights in source order. Masonry handles the visual placement without changing the semantic reading order.

  • Source order

    Items stay in the same DOM order you render, so screen readers and keyboard users do not inherit a visual-only sorting model.

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Measured layout

    The component measures rendered item heights and places each item in the shortest column. It does not rely on experimental CSS masonry support.

    The visual arrangement is decorative; the DOM remains the source of truth.

  • Images and async content

    The root listens for load and error events, then schedules a fresh measurement so late-loading media can settle into the grid.

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Browser compatibility

    ResizeObserver powers responsive measurement in modern browsers while the underlying DOM remains plain semantic HTML.

  • Semantic defaults

    Masonry renders a ul with li wrappers by default. Switch itemAs only when your content has a stronger semantic container.

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 0

    Lorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 1

    Lorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 2

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 3

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 4

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 5

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 6

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 7

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 8

    Lorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 9

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 10

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 11

    Lorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 12

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 13

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 14

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 15

    Lorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 16

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 17

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 18

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 19

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 20

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 21

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 22

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 23

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 24

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 25

    Lorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 26

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 27

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 28

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 29

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 30

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 31

    Lorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 32

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 33

    Lorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 34

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 35

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 36

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 37

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 38

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 39

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 40

    Lorem ipsum dolor sit amet

  • Index 41

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 42

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 43

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 44

    Lorem ipsum dolor sit amet

  • Index 45

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 46

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 47

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

  • Index 48

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

  • Index 49

    Lorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit ametLorem ipsum dolor sit amet

    Use it for feature cards, image captions, release notes, or any content feed with uneven heights.

tsx
"use client";
import { Card, Masonry } from "@g4rcez/components";

function BasicMasonry() {
  return (
    <Masonry columns={3} gutter={16}>
      <Card title="Source order">Items stay in DOM order.</Card>
      <Card title="Measured layout">Heights are measured after render.</Card>
      <Card title="Compatibility">No experimental CSS masonry.</Card>
    </Masonry>
  );
}

Custom Item Width

Wrap an item with MasonryItem to give it an explicit CSS width. A 100% width item reserves a row by itself while the remaining items use the calculated column width.

  • Featured
    This card reserves the full row.
  • Alpha
    Regular column item.
  • Beta
    Regular column item.
tsx
import { Card, Masonry, MasonryItem } from "@g4rcez/components";

function FeaturedMasonry() {
  return (
    <Masonry columns={2} gutter={16}>
      <MasonryItem width="100%">
        <Card title="Featured">This card reserves the full row.</Card>
      </MasonryItem>
      <Card title="Alpha">Regular column item.</Card>
      <Card title="Beta">Regular column item.</Card>
    </Masonry>
  );
}

Controlled Measurement

Use columns and gutter to tune the layout. Changing fresh requests a new measurement, and onLayoutChange exposes the computed columns and height.

Waiting for layout

  • Alpha
    Short card.
  • Beta

    Longer card with more content to demonstrate how the measured layout balances column heights.

    When the measurement changes, the callback exposes the resulting layout shape.

  • Gamma
    Another item in source order.
tsx
"use client";
import { useState } from "react";
import { Button, Card, Masonry, type MasonryLayout } from "@g4rcez/components";

function ControlledMasonry() {
  const [fresh, setFresh] = useState(0);
  const [layout, setLayout] = useState<MasonryLayout | null>(null);

  return (
    <div className="flex flex-col gap-base">
      <Button onClick={() => setFresh((value) => value + 1)}>Measure again</Button>
      <Masonry columns={2} gutter={24} fresh={fresh} onLayoutChange={setLayout}>
        <Card title="Alpha">Short card.</Card>
        <Card title="Beta">Longer card with more content.</Card>
        <Card title="Gamma">Another item.</Card>
      </Masonry>
      <p>{layout ? "Columns: " + layout.columns + ", height: " + layout.height + "px" : "Waiting for layout"}</p>
    </div>
  );
}

Accessibility and Compatibility

Masonry uses measured absolute positioning instead of experimental native CSS masonry. The rendered children stay in source order, and the default structure is a semantic list, which keeps assistive technology and keyboard navigation aligned with the authored content order.

When to use Masonry

Use when

You need the documented Masonry interaction or presentation in a product workflow.

Avoid when

A native HTML element already provides the Masonry behavior you need.

Accessibility

Keep the Masonry labeled and use its documented keyboard interaction. The component preserves visible focus and communicates state without relying on color alone.

  • Keep keyboard focus visible and follow the documented key commands.
  • Provide an accessible name and connect descriptions or errors to the control.