Skeleton loader is a non-interactive placeholder that displays a preview of the UI to visually communicate that content is in the process of loading. Skeleton is used to provide a low fidelity representation of the user interface (UI) before content appears on the page.
Preview
Skeleton vs Loader
Use Skeleton when:
- Content is expected to take more than a few hundred milliseconds to load on average
- You want to show the approximate layout and structure of content being loaded
- Loading complex lists, cards, or detailed content where users benefit from seeing the expected layout
- You need to maintain visual hierarchy during loading states
Use Loader when:
- You need a simple, generic loading indicator
- Loading time is short or indeterminate
- You want to indicate that a process is running without showing layout structure
- You need a compact loading indicator for buttons, small components, or overlays
Usage
Do
- Use when data takes more than 300ms to load on an average connection for our user base.
- Use to represent a general layout of what is being loaded.
- For a repeating list, show 6 items maximum, since it’s enough to give an idea of a layout. For conversations, limit to 3.
- Use skeleton loading for dynamic content, and use actual content for static content that doesn’t change e.g. page title, headings, action components (button, toggles, checkboxes etc.).
- Dynamic content: Content that would change after loading, usually data-based text.
- Static content: Content that can be loaded quickly and wouldn’t change, usually non-data-based text.
- Always match the size of content that will load.
- Always allow content to load gradually. Real content should replace skeleton objects immediately when the data is available.
Don’t
- Use for fast loading less than 300ms.
- Be super detailed trying to represent everything in an interface.
- Use for user action feedback e.g. saving form.
Variants
Default
Animation
Custom
To customize a non-animating Skeleton background color modify the --placeholder-from-color variable with an inline style.
Customize an animating Skeleton by modifying the --placeholder-from-color and --placeholder-to-color variables with an inline style.
Shapes
Avatar
Default sizes match the avatar size. Size is customizable when needed.
Image / Icon
Headings
Prefabricated Combinations
Paragraphs
Avatar + Name
Icon + Text
Messages / Transcript / Comment
Accessibility
For sighted users, they are able to see that there is loading content and no other action is needed until loading completes. Likewise, there is nothing that needs to be added for keyboard users. For users who rely on assistive technology, skeleton’s visual representation of a loading state won’t be accessible without additional labeling.
It's role="status" on the skeleton component, keep in mind, that:
The aria live region role of status has an implicit
aria-livevalue ofpolite, which allows a user to be notified via AT (such as a screen reader) when status messages are added. Theroleofstatusalso has a defaultaria-atomicvalue oftrue, so that updates to the container marked with a role of status will result in the AT presenting the entire contents of the container to the user, including any author-defined labels (or additional nested elements).aria-busystate indicates an element is being modified and that assistive technologies may want to wait until the changes are complete before informing the user about the update. When multiple parts of a live region need to be loaded before changes are announced to the user, setaria-busy="true"until loading is complete. Then set to aria-busy="false". This prevents assistive technologies from announcing changes before updates are done.If you need fully accessible skeleton and loading content, probably you will want to add
aria-live="polite"andaria-busy="false"to corresponding loaded html element content.
<dt-skeleton
v-if="loading"
:aria-label="$i18n('Loading')"
/>
<p
v-else
aria-live="polite"
aria-busy="false"
>
Loaded content.
</p>
References
- Aria-busy, Status role, ARIA22, a11y support status_role
- Carbon DS Loading pattern, Skeleton screens
- Short note on being busy, More Accessible Skeletons