Visually Hidden (Screen Reader Only)
The .sr-only utility hides text from sighted users while keeping it in the accessibility tree — the correct way to label icon buttons, add skip links, and describe badge states.
Quick implementation
/* .sr-only — visually hidden but in the accessibility tree */
.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-focusable — hidden until focused (for skip links) */
.sr-only-focusable:not(:focus):not(:focus-within) {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
/* Usage examples:
Icon button — visible icon, hidden label */
/* */
/* Skip link — appears on keyboard focus */
/* Skip to main content */
/* Live region for status announcements */
/*
Item added to cart
*/Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are an accessibility-focused CSS developer. Implement visually-hidden text patterns for a design system.
Requirements:
1. Provide the canonical .sr-only class using position: absolute, width/height: 1px, clip: rect(0,0,0,0), overflow: hidden, white-space: nowrap.
2. Explain why display: none and visibility: hidden are wrong — they remove elements from the accessibility tree entirely.
3. Explain why clip-path: inset(50%) alone is not sufficient — it doesn't work in some older screen reader + browser combos without the other properties.
4. Provide .sr-only-focusable which undoes the hiding on :focus and :focus-within — required for skip links and "skip to main content" patterns.
5. Show three usage examples in HTML:
a) An icon-only button with for the label.
b) A status badge that appends extra context: (status: online).
c) A skip link: Skip to main content.
6. Show an aria-live region with class="sr-only" for announcing dynamic changes.
Constraints:
- Do not use text-indent: -9999px — it causes a horizontal scrollbar in RTL languages.
- font-size: 0 does not work in some screen readers.
- The clip property is deprecated but still needed for max compatibility alongside clip-path: inset(50%).
Output the CSS class and all three HTML usage examples with brief comments.Why this matters in 2026
Icon-only buttons, status indicators, progress bars, and notification badges carry visual meaning that sighted users parse at a glance. Screen reader users navigate the same interface through the accessibility tree — if an icon button has no text label, it is announced as "button" with no action. The .sr-only pattern bridges this gap: text that lives in the DOM (and therefore in the accessibility tree) but is visually collapsed to a single pixel so it doesn't affect the layout.
The logic
The critical properties are position: absolute (removes from flow), width: 1px; height: 1px (collapses to a point), overflow: hidden; clip: rect(0,0,0,0) (clips any visible overflow), and white-space: nowrap (prevents text from wrapping to a larger height). margin: -1px accounts for any border-box edge case. Do not use display: none or visibility: hidden — both remove elements from the accessibility tree entirely. The sr-only-focusable variant simply undoes the hiding when the element receives focus, making it visible to keyboard users at the moment they tab to it — the classic skip-link pattern.
Accessibility & performance
Elements with .sr-only are part of the document flow as positioned elements and have effectively zero layout impact. They do not affect paint, compositing, or line-box calculations. The pattern is WCAG 1.1.1 compliant for non-text content and the recommended approach in the WAI-ARIA Authoring Practices Guide. For dynamic content announcements, combine .sr-only with aria-live="polite" — the element is invisible but the screen reader announces text updates as they appear in the DOM.