Styling
Customize skeletons with CSS custom properties.
All skeleton visuals are controlled by CSS custom properties. Override them globally or scope them to a specific section.
CSS custom properties
| Property | Default (light) | Default (dark) | Description |
|---|---|---|---|
--bone-base | #e0e0e0 | #2a2a2a | Skeleton background color |
--bone-highlight | #f0f0f0 | #3a3a3a | Highlight color (for shimmer) |
--bone-radius | 4px | 4px | Border radius of skeleton bars |
--bone-duration | 1.5s | 1.5s | Animation duration |
Theming
Override properties on any container to theme a section:
<div
style={{
"--bone-base": "#f5e6d3",
"--bone-highlight": "#faf0e6",
"--bone-radius": "8px",
}}
>
<UserCard user={forceBones} />
</div>Or use a CSS class:
.warm-skeleton {
--bone-base: #f5e6d3;
--bone-highlight: #faf0e6;
}Dark mode
Dark mode works via prefers-color-scheme:
@media (prefers-color-scheme: dark) {
:root {
--bone-base: #2a2a2a;
--bone-highlight: #3a3a3a;
}
}Override these in your own dark mode styles if your app uses a class-based dark mode toggle.
Animations
Add data-bone-animate to any parent element to animate skeletons inside it:
shimmer- horizontal highlight sweeppulse- gentle opacity fade (also kicks in automatically forprefers-reduced-motion: reduce)
{/* Animate a section */}
<div data-bone-animate="shimmer">
<UserCard user={fetchUser()} />
</div>
{/* Animate the entire app */}
<body data-bone-animate="shimmer">Speed is controlled by --bone-duration. Shimmer colors use --bone-base and --bone-highlight.
Accessibility
- Skeleton elements get
aria-busy="true"automatically. pulseanimation activates for users who prefer reduced motion.- Skeleton pseudo-elements have
pointer-events: none.