// preview in
saved for every page

Skeleton

A quiet placeholder in the shape of the content that is on its way. Use it when you know the layout, so the page doesn't jump when the data arrives.

Pattern aria-hiddenServer componentSource ↗
minimal · light · #3fa34d
shape

Installation

Set up Camaleo once (Installation), then import what you need. The skin you load styles it.

import { Skeleton } from "@camaleo/react";

Anatomy

One <span> with a soft shimmer. You set its width and height; shape picks a line or a circle.

shapePlaceholder
[data-slot="skeleton"]data-shape="line | circle"

Examples

Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above.

minimal · light · #3fa34d

Line and circle

shape="circle" for avatars and icons, the default line for titles and text. Size each one like the thing it stands for.

A paragraph of text

Vary the line widths and make the last one short. Equal bars look like a block, not like text.

From placeholder to content

Click it. The card keeps its header, body and footer while loading, and the button stays real and usable.

Balance

No jump when it loads

Click it. Each placeholder sits in a box with the line height of the text it waits for, so nothing below moves.

A list, marked busy

Skeletons are hidden from screen readers. Put aria-busy="true" and a name on the container, so people know the list is loading.

InvoiceCustomerTotal

A table while it loads

Keep the real column headers and fill only the cells. People can already read what the table will hold.

Skeleton: you know what is coming

Spinner: an action is running

Skeleton or Spinner?

Skeleton when you know what is coming, like a profile or a list. Spinner when an action is running, like saving.

In context

Skeletons stand in for whole pieces of UI. These are the loading states you can copy, in the skin you picked.

Profile

Profile headerCard · Skeleton

Activity

Activity postCard · Skeleton

Help center

Billing
·
Help articleCard · Badge · Skeleton

Guidelines

DoCopy the shape of the content.

An avatar circle and two lines of the right size: the page looks the same when the data arrives.

Don’tOne big gray box.

It says nothing about what is coming, and the page jumps when the real layout appears.

DoMark the region busy.

Give the container a name and aria-busy="true", and remove it when the content is in.

Don’tSkeletons in place of buttons.

You already know the actions. Show the real buttons, disabled if they can't work yet, so people see what they will be able to do.

Props

PropTypeDefaultDescription
shape"circle" | "line""line"Shape of the placeholder: line for text, circle for avatars and icons.

Native <span> attributes pass through. Set the size with style or className.

Styling hooks

Attributes

data-shapeline · circle
aria-hidden"true", always

Tokens it reads

Color

--cml-fg--cml-surface

Shape & size

--cml-radius-control--cml-radius-pill

Accessibility

—Not focusable. A skeleton is only a picture of the layout.
Was this page helpful? · Edit this page on GitHub