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-busylives 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