abaabil

Skeleton

8th lightest of the thirty-two, by js weight

A placeholder holding the space content will occupy. Its whole accessibility story is subtraction: the bars are always hidden, and one announcement replaces all of them.

Example (a11y tier)

Loading messages

Import

import Skeleton from 'abaabil/skeleton'         // structure only
import Skeleton from 'abaabil/skeleton/styled'  // + CSS
import Skeleton from 'abaabil/skeleton/a11y'    // + hidden, one status

The bars are always hidden, with no way to opt out

Grey bars are a picture of a layout. Read aloud they are a dozen empty boxes, which tells someone nothing except that something is wrong. So the a11y tier marks every skeleton aria-hidden, always. It is not a prop, because there is no case where announcing them helps.

What replaces them is one announcement for the region. Ten skeletons in a list should produce one “Loading messages”, not ten, so label belongs on the outermost one and nowhere else.

aria-busy is not set here, on purpose

It belongs on the element whose content is loading, which is your container, not on the placeholder standing inside it. Setting it on the skeleton says “this grey box is loading”, which is both true and useless. It is a common enough mistake that this component refuses to make it for you.

<ul aria-busy={loading}>
  {loading
    ? <Skeleton lines={3} label="Loading messages" />
    : messages.map(...)}
</ul>

Sizing

A skeleton's size is whatever the content it replaces happens to be, and no set of variants covers that, so width and height are passed straight through as custom properties. lines draws a paragraph, with the last bar short, because otherwise every caller writes the same loop and the block reads as a table rather than as prose.

Props

PropTypeDefaultTierDescription
shape'text' | 'rect' | 'circle''text'allApplied as data-shape.
linesnumber1allSeveral text bars, the last one short.
widthstringallAny CSS length, as --skeleton-width.
heightstringallAny CSS length, as --skeleton-height.
labelstringa11yAnnounced once. One per loading region.
classNamestringallMerged with the base class.