Guide

Measured Heights

Use ResizeObserver, known dimensions, and estimates without layout surprises.

MasonryBalanced and MasonryVirtual need item heights. Masonix can measure the rendered DOM, or you can provide known heights before render.

Measured cards

Use measurement when card height depends on rendered content.

Performance7 min read

Designing feeds that still feel fast at 10,000 items

A practical guide to windowing, measurement, and when placeholders improve the scroll experience.

Images4 min read

Treat image dimensions as layout data

Known width and height values let the layout settle before media finishes loading.

Accessibility5 min read

Masonry grids can still be semantic

Source order, list roles, and item metadata matter more than the visual column a card lands in.

Responsive6 min read

Container breakpoints beat viewport assumptions

Use breakpoint maps when the component lives inside panels, sidebars, or resizable workspaces.

Design8 min read

Composing card systems around unknown height

Small differences in copy, badges, and media ratios add up. Balanced placement keeps the page calm.

<MasonryBalanced
  items={articles}
  columns={{ 0: 1, 640: 2 }}
  gap={16}
  estimatedItemHeight={220}
  itemKey={(article) => article.id}
  render={({ data }) => <ArticleCard article={data} />}
/>

estimatedItemHeight is the first height Masonix uses before measurement. Pick a realistic average so the first layout is close to the final layout.

Masonix measures the item wrapper's border box, including its padding and borders. Use the Masonix gap prop for space between items; vertical margins are outside the measured box and can make positioned items overlap.

Known image heights

Use getItemHeight when each item has dimensions.

Marfa, TX

Desert dawn

Seattle, WA

Glass house

Reykjavik, IS

Blue hour

Lisbon, PT

Courtyard

Brooklyn, NY

Studio wall

Kyoto, JP

Quiet arch

Busan, KR

Sea path

Portland, OR

Green room

<MasonryBalanced
  items={photos}
  columns={{ 0: 1, 560: 2, 860: 3 }}
  gap={14}
  defaultWidth={960}
  itemKey={(photo) => photo.id}
  getItemHeight={(photo, _index, columnWidth) =>
    Math.round(columnWidth * (photo.height / photo.width))
  }
  render={({ data, width }) => <PhotoCard photo={data} width={width} />}
/>

Known heights reduce layout shift and make SSR output closer to the hydrated browser layout.

Stability rules

  • Always provide itemKey when items can reorder or filter.
  • Use minItemHeight when cards can temporarily measure too small while media or fonts settle.
  • Keep the measured item wrapper stable; avoid swapping the whole card shell during loading.
  • Return finite, non-negative pixel heights from getItemHeight. Invalid known heights fall back to estimatedItemHeight.

On this page