Masonry Components
Real-world Examples
Photo Gallery
Photo 1
Photo 3
Photo 5
Photo 7
Photo 2
Photo 4
Photo 6
Photo 8
Content Cards
Card Title 1
Short description.
Card Title 2
This card has more content and will be taller than the others. Lorem ipsum dolor sit amet.
Card Title 3
Medium content here.
Card Title 4
Another card.
Card Title 5
This one has a bit more text to show the masonry effect working properly with different heights.
Card Title 6
Short text.
Basic Masonry Layout
2 Columns
1
3
5
2
4
6
3 Columns
1
4
7
2
5
8
3
6
9
4 Columns
1
5
2
6
3
7
4
8
Responsive Masonry
1 → 2 → 3 → 4 Columns
Try resizing your browser: 1 col on mobile, 2 on small, 3 on medium, 4 on xl screens
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
2 → 3 → 4 Columns
Starts at 2 columns on mobile
01
03
05
07
02
04
06
08
Gap Variations
Small Gap (gap=1)
1
4
2
5
3
6
Large Gap (gap=6)
1
4
2
5
3
6
Custom Gap (X=6, Y=2)
1
4
2
5
3
6
Responsive Gap
Gap increases with screen size
1
3
5
2
4
6
Custom Column Styling
Columns with Background
1
4
2
5
3
6
Sortable Masonry Component
Sortable Masonry (variable heights, drag across columns)
The flat order is the concatenation of the columns (top to bottom, left to right). After a drop the list is evenly redistributed — an item close to a column boundary may shift to the neighbouring column : the invariant is the order, not the column.
1
2
3
4
5
6
7
8
9
10
<SortableMasonry columns={ { xs : 2 , md : 3 } } gap={ 4 } defaultItems={ cards } renderItem={ card => <SortableGridItem>...</SortableGridItem> }/>Controlled Masonry (live flat order)
Flat order :1 , 2 , 3 , 4 , 5 , 6 , 7 , 8
1
2
3
4
5
6
7
8
<SortableMasonry items={ cards } onReorder={ next => setCards( next ) }/>Disabled Dragging (global toggle + per-item locks)
The 🔒 cards are always locked (per-item disabled).
1
2
3
4
5
6
<SortableMasonry disabled={ saving } // container level : freezes every item renderItem={ card => ( <SortableGridItem disabled={ card.locked }> // item level : explicit value wins )}/>// note : a disabled item cannot be grabbed, but it is not pinned —// it still shifts when its neighbours are reorderedAsync Reorder with API Call (optimistic revert on failure)
1
2
3
4
5
6
<SortableMasonry defaultItems={ cards } onReorder={ ( items ) => api.saveOrder( items ) }/>// onReorder may return a promise : a rejection restores the previous orderProps Reference
| Prop | Type | Description |
|---|---|---|
items / defaultItems | Array | Controlled / uncontrolled flat list (each item needs a stable id) |
onReorder | function | (items, { from, to, item }) => void | Promise — flat indexes ; a rejected promise reverts the order (uncontrolled) |
renderItem | function | (item, indexInColumn) => SortableGridItem element |
columns | number | object | Column count or responsive object { xs, sm, md, lg, xl, xxl } (sequential distribution) |
handle | boolean | Show an overlay drag handle (default false : whole items draggable) |
getItemId / disabled / gap / ... | — | Same contract as SortableGrid ; other props forwarded to the Grid container |