Skip to content

CdsSkeletonLoader

A skeleton shows the shape of the future content while the data is loading: instead of an empty screen the user immediately sees where the heading, the text and the buttons will appear. The ready-made types (type) are assembled from "bones" — blanks for an avatar, a line of text, a button or a table.

Storybook GitLab
Test coverage: 94% — good coverage
API in specs
12 / 12 props, events, slots and exposed members with a test
Test cases
18 unit · 0 browser
Known bugs
1 pinned by an it.fails test
Code coverage
94.1% lines · 85.2% branches measured in v4.0.0-alpha.13
A11y (axe)
no violations in 11 stories measured in v4.0.0-alpha.11

A skeleton fits the first load of a block or a page. For waiting inside a single action — submitting a form, saving — take the loading prop of CdsButton or CdsProgressCircle. If there is no data at all, show CdsEmptyState.

Anatomy ​

A skeleton is a container with nested "bones": every bone repeats the shape of one element of the future content. The list-item-avatar-two-line, actions type unfolds into a circle for the avatar, two lines of text and two buttons.

Variations ​

Types ​

The type prop takes a ready-made structure from the catalog: article — a heading and a paragraph, card — an image with a heading, table — a header, rows and a footer.

Your own structure ​

The type can be described with a string: a comma-separated list puts bones one after another, and @N repeats a bone N times. An array of strings works the same way as a comma-separated list.

Catalog of types ​

All the built-in types and their structures. Any of them can be inserted into your own string as a bone — heading, table-row@3.

Storybook

Sizes ​

The width, height, min-width and max-width props set the size of the container — the bones stretch along it. Give the skeleton the same size as the future content, so that the layout does not jump when the data arrives.

Replacing the content ​

Put the content into the default slot: while loading is true, the skeleton is visible in its place, and afterwards — the content itself, with no wrapper. The loading-text prop sets the aria-label — a screen reader will announce what exactly is loading.

Without animation ​

The boilerplate prop turns the shimmer off. Such a skeleton is a blank for mockups and static prototypes; on a live screen it does not communicate waiting.

Guidelines ​

Scenarios ​

List of participants ​

While the list is loading, type="list-item-avatar-two-line@3" holds the space for three records: an avatar and two lines of text in each. The slot hands over the ready list as soon as the data arrives, so no v-if is needed in the template.

Table of contracts ​

A skeleton of table-heading, table-row@3 repeats the header and the rows of the table, and loading-text explains the wait to the screen reader. The number of rows matches the page size of the data — after loading, the height of the block does not change.

Page frame ​

On the first load of a page the blocks load independently, so each one has its own skeleton: the list of sections is list-item@4, the content is heading, paragraph, paragraph. A block that is ready appears right away, without waiting for its neighbor.

API ​

Props

NameTypeDefaultDescription
boilerplateboolean | undefinedfalseBoilerplate mode: turns the shimmer animation off (for prototyping).
heightstring | number | undefined—Component height
loadingboolean | undefinedfalseShows the skeleton instead of the slot content while loading.
loadingTextstring | undefined—Text for the aria-label while loading.
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
themestring | undefined—Component theme
type(string & {}) | "text" | "block" | "article" | "button" | "table" | "divider" | "subtitle" | "chip" | "avatar" | "actions" | "heading" | "sentences" | "paragraph" | "card" | "card-avatar" | "date-picker" | "date-picker-options" | "date-picker-days" | "list-item" | "list-item-avatar" | "list-item-two-line" | "list-item-avatar-two-line" | "list-item-three-line" | "list-item-avatar-three-line" | "table-heading" | "table-thead" | "table-tbody" | "table-row-divider" | "table-row" | "table-tfoot" | readonly ((string & {}) | "text" | "block" | "article" | "button" | "table" | "divider" | "subtitle" | "chip" | "avatar" | "actions" | "heading" | "sentences" | "paragraph" | "card" | "card-avatar" | "date-picker" | "date-picker-options" | "date-picker-days" | "list-item" | "list-item-avatar" | "list-item-two-line" | "list-item-avatar-two-line" | "list-item-three-line" | "list-item-avatar-three-line" | "table-heading" | "table-thead" | "table-tbody" | "table-row-divider" | "table-row" | "table-tfoot")[] | undefined'block'Skeleton type: a predefined preset or an arbitrary structure string (or an array of strings).
widthstring | number | undefined—Component width

Slots

NameTypeDescription
defaultanyContent rendered instead of the skeleton once the loading is done.