screen-readers
Visually hiding text while keeping accessible labels and descriptions.
Overview
| Class | Declarations |
|---|---|
sr-only | position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
|
sr-only visually clips text while leaving it available to assistive technologies. Use it for meaningful labels and descriptions; it is different from display:none, hidden or aria-hidden.
Examples
Hide text visually
The summary’s text names a real disclosure. sr-only hides the words visually; its decorative icon remains visible.
<details> <summary class="inline-flex items-center p-sm b:1px|solid|var(--color-line-base) r-sm cursor:pointer"> <span id="target" class="sr-only">Canvas settings</span> <svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5"> <path d="M3 5h14 M3 10h14 M3 15h14" /> </svg> </summary> <label class="flex items-center gap-sm mt-md"> <input type="checkbox"> Show grid </label></details><p class="mb:0 mt-md font-xs text-muted">Accessible name: Canvas settings</p>Generated CSS
@layer utilities { .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0 }}Tab to the visible summary and press Enter or Space to open it. The hidden text supplies its accessible name; the annotation below makes that name visible for this lesson.
Label icon-only controls
Give an icon-only button a text alternative that describes its action. This native reset button restores the Project name field after you edit it.
<form class="grid justify-items:start gap-md"> <label class="grid gap-xs w:240px max-w:100%"> Project name <input type="text" value="Canvas" class="w:100%"> </label> <button type="reset" class="inline-flex items-center gap-sm"> <span id="target" class="sr-only">Reset project name</span> <svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5"> <path d="M4 8a6 6 0 1 1 0 5 M4 3v5h5" /> </svg> </button></form><p class="mb:0 mt-md font-xs text-muted">Accessible name: Reset project name</p>The button stays visible, focusable and operable. Its SVG is decorative; the hidden text supplies the name without adding a second focus stop.
Avoid hiding interactive content
Keep the editable control and its label visible. Link a separate hidden description with aria-describedby.
<label for="target" class="block mb-xs">Project name</label><input id="target" type="text" value="Canvas" aria-describedby="name-help" class="w:240px max-w:100%"><p id="name-help" class="sr-only">Use a descriptive project name.</p><p class="mb:0 mt-md font-xs text-muted">Accessible description: Use a descriptive project name.</p>The for and id connect the visible label to the input. aria-describedby adds supporting information without replacing that name. Hiding a focusable input with sr-only would leave sighted keyboard users without a visible target.
Apply conditionally
Keep the reset label visible below sm and visually hide it at that breakpoint. Resize the viewport; the accessible name stays “Reset project name.”
<form class="grid justify-items:start gap-md"> <label class="grid gap-xs w:240px max-w:100%"> Project name <input type="text" value="Canvas" class="w:100%"> </label> <button type="reset" class="inline-flex items-center gap-sm"> <span id="target" class="sr-only@screen@sm">Reset project name</span> <svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.5"> <path d="M4 8a6 6 0 1 1 0 5 M4 3v5h5" /> </svg> </button></form><p class="mb:0 mt-md font-xs text-muted">Accessible name: Reset project name at every width</p>Only the text label changes its visual treatment. The button remains visible and keeps its native action. The screen condition leaves the text visible in print.