shadcn.io is not affiliated with official shadcn/ui
Basic Card Skeleton Block for Solid
A gardening guide card that loads in place: a drawn picture, a topic line, a title, a three-line summary and a reading time come in over bars when you press Load, above a real Read guide button.
Installation
Overview
Show a content card while it loads, then swap the content in without moving anything, with this basic card skeleton for Solid with Ark UI. A hairline frame with a plus mark on each corner holds three bands: a drawn picture, the text and a foot. The card is Selvedge's guide on planting a native hedge; the structure and the Read guide button are real from the first paint, and the picture, the topic line, the title, the three-line summary and the reading time are Skeleton bars that become the guide in the same place. The picture is drawn in greyscale rather than photographed, the summary is a Skeleton Text effect whose words come in one after another, and the bands are ruled by Guides. Read guide is an outline Button that is unavailable until the guide is in, and says it is not wired in this demo when you press it. It's built from Skeleton, Skeleton Text, Button and Guides, with a CSS entrance only. For article, guide and listing cards.
FAQ
What stays local, and how do I wire it to a real query?
Nothing is fetched. The guide is typed in GUIDE. 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 card from your query's pending state, or use the bars as a Suspense fallback and render the real content when it arrives. Keep one component for the bars and the data so they can't drift apart.
Why doesn't the card jump when the data arrives?
The picture has a fixed 16:9 box that holds the bar and the drawing in the same place, and the summary's bars and words share one grid cell, so the taller of the two sets the height. The topic line, the title and the reading time are Cells that do the same. The frame and the button are real in both phases, and the polite line reserves two lines, so the card is exactly as tall before, during and after loading at every width.
How do I use a real photograph?
The picture is a drawn scene (Pic around the Scene component), so the block ships no image file. For a photograph, replace the Scene inside Pic with <img alt="" className="size-full object-cover" src={guide.cover} /> and keep the rest: the bar still holds the box until the image is ready. Set the image's width and height or keep the 16:9 box so it can't reflow, and give it real alt text on the wrapper.
Why is Read guide unavailable while it loads?
A control that opens the guide can't act before the guide exists, so the button is aria-disabled until the data is in rather than disabled, which would drop it out of the tab order and move focus. It stays in the layout in both phases, so nothing shifts when it becomes available. In your app, make it a link to the guide's page.
Is it accessible?
The card is marked busy while it loads and carries a screen-reader-only "Loading guide…", 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.