feedback
Skeleton
Placeholder shapes that hold the place of content while it loads.
CSS onlyPlain classes; no JavaScript in any stack.
Usage
Shape the skeleton like the content it replaces. Mark the container aria-busy="true" and tell screen readers what is loading.
Loading the lesson
<div class="ca-card w-full max-w-sm" aria-busy="true">
<p class="sr-only" role="status">Loading the lesson</p>
<div class="flex items-center gap-3" aria-hidden="true">
<span class="ca-skeleton ca-skeleton--circle"></span>
<span class="ca-skeleton ca-skeleton--text max-w-40"></span>
</div>
<div class="grid gap-2" aria-hidden="true">
<span class="ca-skeleton ca-skeleton--text"></span>
<span class="ca-skeleton ca-skeleton--text"></span>
<span class="ca-skeleton ca-skeleton--text max-w-48"></span>
</div>
</div>Examples
Variants
A line of text, a circle for an avatar, and a block for an image or a card.
<div class="grid w-full max-w-sm gap-4" aria-hidden="true">
<span class="ca-skeleton ca-skeleton--text"></span>
<span class="ca-skeleton ca-skeleton--circle"></span>
<span class="ca-skeleton ca-skeleton--block"></span>
</div>Guidance and accessibility
When to use
- Use skeletons when content takes a moment and its layout is known, so the page does not jump when it arrives.
- Keep them close to the final layout: the same number of lines, the same avatar size.
- For a short wait in one control, such as a button that saves, show progress in that control instead.
Accessibility
- Hide the shapes from screen readers with
aria-hidden="true"; they carry no content. - Say what is loading in a
role="status"element, visually hidden if the shapes are enough for sighted people. The example uses Tailwind’ssr-only; any visually hidden class works. - Set
aria-busy="true"on the container while it loads and remove it when the content is in. - The pulse only runs when people allow motion.
Classes
Generated from the component contract. Parts use __, modifiers use --.
| Class | Kind | Use it for |
|---|---|---|
ca-skeleton | Component | A placeholder shape. Add one variant. |
ca-skeleton--text | Variant | One line of text, as tall as the text around it. |
ca-skeleton--circle | Variant | A round shape, such as an avatar. |
ca-skeleton--block | Variant | A larger area, such as an image or a chart. |
Skins
The same markup, dressed by each skin. Structure and behavior stay the same; only the look changes.
Base skin
Neutral grayscale starting point; product skins extend it and change what differs.
Loading the lesson
Calaca skin
The Calaca UI brand: hueso paper and tinta ink, cempasúchil marigold, rosa and jade.
Loading the lesson
Proof skin
Pilot skin pushed far from base: square, heavy, offset shadows, larger targets.
Loading the lesson
Crossview skin
The CrossView proofing table: cool ground, bond-paper sheets, rule-grey hairlines, one red mark.
Loading the lesson
Framework notes
Link the prebuilt stylesheet of your skin next to your brand theme. No build step.
<link rel="stylesheet" href="theme.css" />
<link rel="stylesheet" href="ca-base.css" />In Astro, Vite and other Tailwind projects, import Calaca after Tailwind and your theme in your main stylesheet.
@import "tailwindcss";
@import "./theme.css";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";Same stylesheet as above; write the classes in className.
<button className="ca-button ca-button--primary ca-button--md" type="button">Save changes</button>