ProductBrand
Join us
Foundations
  • Introduction
  • Guidelines
  • Colors
  • Typography
  • Breakpoints
  • Elevation
  • Patterns
Identity
  • Logos
  • Mr Rogo
  • Assets
Components
  • Button
  • Carousel
  • CTA Headline
  • Navigation Menu
  • Popover
  • Separator Dot
  • Sheet
  • Skeleton
  • Video Player

Skeleton

The placeholder a marketing surface holds while its content is in flight.

Loading the featured story
Loading the featured story

Hold the shape, not a spinner

A skeleton is worth reaching for when the layout already knows what is coming and only the content is late. It keeps the box that the content will land in, so nothing around it moves when the swap happens. Where the shape is not known ahead of time, do not guess one: leave the space empty.

tsx
import { Skeleton, SkeletonGroup } from "@rogo-technologies/brand/skeleton";

<SkeletonGroup className="flex flex-col gap-4" label="Loading the featured story">
  <Skeleton className="aspect-[16/10] w-full rounded-xl" />
  <Skeleton variant="text" className="type-marketing-body-medium-md" width="60%" />
</SkeletonGroup>;

The site's own case is the header: the Resources panel's feature card is the newest newsroom post, fetched by the header after the page rather than rendered into it, so the pages that hold no CMS content stay static. The panel holds the card's column at these proportions until it arrives.

Props

PropTypeDefaultWhat it does
variant"block" | "text""block"block takes its height from you; text is 1em tall.
tone"light" | "dark""light"Which ground it sits on.
widthnumber | stringnot setCSS width; a number is pixels. Tailwind width classes work too.

SkeletonGroup takes a label (default "Loading") and any div props.

Sizing

variant="text" is 1em tall, so it takes its height from the type it stands in for: give it the same type-marketing-* utility as the line it replaces and the placeholder and the copy occupy the same band. A block needs a height from you, usually an aspect-* or a h-*.

It stays square

Like every other marketing surface. Add a radius only where the thing being replaced carries one, such as the nav panel's picture (rounded-xl) or a pill. A placeholder that is a different shape from its content reads as the layout breaking rather than as content arriving.

Announced once

Skeleton is aria-hidden: there is nothing in it to read. SkeletonGroup is the live region that says the thing is loading, so a card standing in for a picture and two lines announces once rather than three times. Wrap every loading state in one, including a single box.

Pass your own role or aria-label to a Skeleton only when that one placeholder genuinely is the whole loading state and you are describing it yourself; the component then leaves it in the accessibility tree.

Motion

One animate-pulse, dropped entirely under prefers-reduced-motion. No shimmer sweep: the marketing surfaces are quiet, and a travelling highlight on a page of stills draws the eye to the one thing that has not arrived.

PreviousSheet
NextVideo Player
Made in NYC© 2026 Rogo Technologies Inc.

Design at Rogo

We’re redesigning an entire industry. Come design it with us.

See open roles

Design at Rogo

  • How we workThe mission of design at Rogo, and the open roles
  • About RogoThe company and the product