Skeleton list — accessibility

Keyboard

  • Nothing inside is focusable; there is no tab stop between the top bar and whatever follows the list.
  • While the skeleton is up, the region the user was in has no interactive content — a host that took focus away must give it back when the rows arrive.

ARIA

  • The wrapper sets aria-busy="true", which is the one signal the component makes. It tells assistive technology that this region is being updated rather than that it is empty.
  • No role="status" and no live region: a first load is a navigation the user initiated, not an event to interrupt them with.
  • The rows carry no roles — they are not list items and must not be announced as such, because they stand for nothing yet.
  • When the data lands, remove the whole block. Leaving aria-busy="true" on a filled region is worse than never setting it.

Focus

  • No focusable descendants and no focus ring.

Contrast

  • The bars and circles come from the surface scale and are intentionally low-contrast; they represent absent content, so AA text thresholds do not apply.

Known limits

  • The shimmer ignores prefers-reduced-motion.
  • The switch from busy to ready is not announced; a screen-reader user has to go back and re-read the region to notice the rows.
  • aria-busy lives on the wrapper only — a host that renders the skeleton next to real content, rather than in place of it, gives an inaccurate picture of what is loading.

Source: docs/loading/skeleton-list.a11y.md · GitLab