Accessibility

screen-readers

Visually hiding text while keeping accessible labels and descriptions.

Overview

ClassDeclarations
sr-onlyposition: 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.

Hide text visually
Visible annotations explain the actual accessible name or description. Use Tab to reach the visible native control; its hidden label is not a separate focus target.
<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.

Label icon-only controls
Visible annotations explain the actual accessible name or description. Use Tab to reach the visible native control; its hidden label is not a separate focus target.
<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.

Avoid hiding interactive content
Visible annotations explain the actual accessible name or description. Use Tab to reach the visible native control; its hidden label is not a separate focus target.
<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.”

Apply conditionally
screen-readers: Apply conditionally controls
Visible annotations explain the actual accessible name or description. Use Tab to reach the visible native control; its hidden label is not a separate focus target.
<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.



© 2026 Aoyue Design LLC.MIT License
Trademark Policy