Accessibility
Accessibility utilities.
Examples
<button class="btn btn-icon" type="button">
<svg class="icon" aria-hidden="true"><use href="#icon-search"></use></svg>
<span class="sr-only">Search</span>
</button>.sr-only is how an icon-only control gets a name. It stays in the accessibility tree — unlike display: none, which removes it, and unlike visibility: hidden, which does the same.
- VoiceOver still announces "list, 2 items"
- because the role survived the missing markers
<ul class="list-semantic" role="list">
<li>VoiceOver still announces "list, 2 items"</li>
<li>because the role survived the missing markers</li>
</ul>Removing list markers removes list semantics in VoiceOver. role="list" puts them back, and this class is the pairing made explicit.
Tokens 0
Level 2, declared on .sr-only itself. Set any of them on that selector to restyle this utility without touching the skin.
None. It reads the skin's tokens directly.
Variants and states
Variants
None. It is one shape, and the page does the rest.
Inside it
.list-semantic.sr-only-focusable
State it reads
Read from the platform, never mirrored into a class that could disagree with it.
:focus
Before you ship it
What you have to do 3 requirements
- Never reach for
.sr-onlyto hide something from everyone. It does the opposite: invisible on screen, fully present to assistive technology. Usehiddenfor content nobody should get. - Put
.sr-only-focusableon something focusable. It reveals itself on focus, so on a<div>it can never appear at all. .list-semanticis for a list whose markers are content, not for decoration. Using it to get bullets back on a menu says the wrong thing to a screen reader about what that menu is.@rootis stated because there is no structural answer: three independent classes give the guesser nothing to prefer, and it picked.list-semantic, the least used of the three. A tag runs to the end of the docblock, which is why this is the last line in it. @root .sr-only
src/css/utilities/a11y.css · npx mostlycss add a11y