Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

Masonry

Pinterest-style vertical-pack grid using CSS columns for efficient masonry layout without JavaScript.

Components Masonry
layout static
<arc-masonry>

Overview

Masonry is a layout primitive that arranges variable-height children into a Pinterest-style vertical-pack grid using pure CSS columns. Items flow top-to-bottom within each column, filling vertical space efficiently without leaving gaps — the classic masonry pattern used in image galleries, card feeds, and content discovery interfaces. The component uses CSS `column-count` and `column-gap` under the hood, which means layout is handled entirely by the browser with zero JavaScript overhead. Each child element is automatically placed into the shortest column, creating a tightly packed grid that adapts to varying content heights. The `columns` prop controls the number of columns, while the `gap` prop maps to design system spacing tokens for consistent rhythm. Use Masonry when your content items have naturally varying heights — image galleries, blog post cards, testimonial collections, or any feed where uniform row heights would waste space. For uniform aspect-ratio grids, use AspectGrid instead. For responsive column-to-stack behavior, combine Masonry with ResponsiveSwitcher.

Guidelines

When to use

  • Use for image galleries with varying aspect ratios
  • Use for card feeds where content height varies (blog posts, testimonials, products)
  • Set columns to match the expected viewport width — 2 for narrow, 3-4 for wide
  • Combine with ResponsiveSwitcher to reduce columns on smaller screens
  • Use gap="md" for most card-based layouts; gap="sm" for dense image grids

When not to use

  • Do not use Masonry for uniform-height content — use a regular CSS grid or AspectGrid instead
  • Do not set very high column counts (>5) as it creates unreadably narrow columns
  • Do not expect left-to-right reading order — masonry flows top-to-bottom per column
  • Do not nest Masonry inside Masonry
  • Do not use for layouts that require precise item ordering — column flow is determined by height

Features

  • Pure CSS columns layout — zero JavaScript for masonry positioning
  • Configurable column count via the `columns` prop
  • Design-token-based gap spacing (sm, md, lg) for consistent rhythm
  • Vertical-pack flow fills shortest columns first for tight packing
  • Break-inside: avoid ensures children are never split across columns
  • Lightweight wrapper with no resize observers or layout calculations
  • CSS part: `grid` for targeted ::part() styling

Preview

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6

Usage

<arc-masonry columns="3" gap="md">
  <arc-card>Short content</arc-card>
  <arc-card>Taller content with more text that wraps to multiple lines</arc-card>
  <arc-card>Medium content</arc-card>
  <arc-card>Another short card</arc-card>
  <arc-card>Variable height content for masonry layout</arc-card>
  <arc-card>Brief</arc-card>
</arc-masonry>
import { Masonry, Card } from '@arclux/arc-ui-react';

function ImageGallery() {
  return (
    <Masonry columns={3} gap="md">
      <Card>Short content</Card>
      <Card>Taller content with more text</Card>
      <Card>Medium content</Card>
      <Card>Another short card</Card>
    </Masonry>
  );
}
<script setup>
import { Masonry, Card } from '@arclux/arc-ui-vue';
</script>

<template>
  <Masonry :columns="3" gap="md">
    <Card>Short content</Card>
    <Card>Taller content with more text</Card>
    <Card>Medium content</Card>
    <Card>Another short card</Card>
  </Masonry>
</template>
<script>
  import { Masonry, Card } from '@arclux/arc-ui-svelte';
</script>

<Masonry columns={3} gap="md">
  <Card>Short content</Card>
  <Card>Taller content with more text</Card>
  <Card>Medium content</Card>
  <Card>Another short card</Card>
</Masonry>
import { Component } from '@angular/core';
import { Masonry, Card } from '@arclux/arc-ui-angular';

@Component({
  imports: [Masonry, Card],
  template: `
    <arc-masonry [columns]="3" gap="md">
      <arc-card>Short content</arc-card>
      <arc-card>Taller content with more text</arc-card>
      <arc-card>Medium content</arc-card>
      <arc-card>Another short card</arc-card>
    </arc-masonry>
  `,
})
export class GalleryComponent {}
import { Masonry, Card } from '@arclux/arc-ui-solid';

function ImageGallery() {
  return (
    <Masonry columns={3} gap="md">
      <Card>Short content</Card>
      <Card>Taller content with more text</Card>
      <Card>Medium content</Card>
      <Card>Another short card</Card>
    </Masonry>
  );
}
import { Masonry, Card } from '@arclux/arc-ui-preact';

function ImageGallery() {
  return (
    <Masonry columns={3} gap="md">
      <Card>Short content</Card>
      <Card>Taller content with more text</Card>
      <Card>Medium content</Card>
      <Card>Another short card</Card>
    </Masonry>
  );
}
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-masonry — requires masonry.css + base.css (or arc-ui.css) -->
<div class="arc-masonry">
  <div class="masonry">
    Masonry
  </div>
</div>
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-masonry — self-contained, no external CSS needed -->
<div class="arc-masonry" style="display: block">
  <div style="column-count: 3; column-gap: 16px">
    Masonry
  </div>
</div>

API

columns number 3
Number of columns in the masonry grid. The browser distributes children across columns to minimize overall height difference.
gap 'sm' | 'md' | 'lg' 'md'
Spacing between columns and rows, mapped to design system spacing tokens (--space-sm, --space-md, --space-lg).

See Also