Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Gallery Masonry Skeleton Block for Radix UI

A mood board that loads in place: six pictures of unequal shapes in balanced columns, two on a phone and three on a wide screen, bars that become drawn scenes with a caption when you press Load.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Show a masonry board while its pictures load, then swap them in without moving anything, with this gallery masonry skeleton for React with Radix UI. A hairline frame with a plus mark on each corner holds a band heading ("Studio refresh") over six pictures in columns, from Gromwell, a mood-board app: two columns on a phone and three from the medium breakpoint. The heading and the columns are real from the first paint; each picture, its one-line caption and the "6 pictures" count are Skeleton bars that become the board in the same place when you press Load. The pictures are drawn scenes in six different ratios (3:4, 1:1, 4:5, 5:4, 2:3 and 4:3), never photographs, and each box comes from its typed ratio so the columns balance by their heights and nothing moves. It's built from Skeleton, Guides and Button, with a CSS entrance only. For mood boards, inspiration feeds and any gallery of unequal pictures.

FAQ

What stays local, and how do I wire it to a real query?

Nothing is fetched. The six pictures are typed in PINS, Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the region from your query's pending state, or use the bars as a Suspense fallback and render the real tiles when they arrive. The bars are derived from the same data as the content, so keep one component for both.

How do the columns balance?

With CSS columns: the list is two columns on a phone and three from md, and each tile refuses to break across them, so the browser fills them evenly by height. The reading order is column by column, which is the order of the list in the page, so the keyboard and a screen reader follow it too.

Why don't the tiles jump when the pictures arrive?

Each bar and its data sit in one grid cell, so the larger of the two sets the cell's box and the swap changes nothing around it. Each picture's box comes from its typed ratio as a literal class (aspect-[3/4], aspect-square…), so the columns balance on the same heights before and after. The frame and the labels are real in both phases and the polite line reserves two lines, so the panel is exactly as tall before, during and after loading at every width.

How do I use real photographs?

Swap the Pic scene for an img filling the same box (object-cover). Keep the ratio in your data, from the image's own width and height, and set it as the box before the image decodes.

Is it accessible?

The region is marked busy while it loads and carries a screen-reader-only "Loading pictures…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant. Each tile is a figure with its picture described and its caption beneath.