VisuallyHidden
Text that assistive technology announces but the page doesn't show.
On this page
VisuallyHiddenExample.tsx
import { Link } from "@/components/Link";
import { VisuallyHidden } from "@/components/VisuallyHidden";
export function VisuallyHiddenExample() {
return (
<p>
<Link href="/design-system/tokens">
Read more <VisuallyHidden>about design tokens</VisuallyHidden>
</Link>
</p>
);
}Examples
Reveal the hidden text
Shows the hidden text in the examples below, outlined. Screen readers get the same as before.
Icon-only button
Announced as: “Mark as done, button”
Extra link context
Announced as: “Read more about tokens, link”
Hidden heading
Projects
- Personal site
- Component library
Announced as: “Projects, heading level 4”
Hidden form label
Announced as: “Search the design system, search field”
Skip link (Tab to it)
Announced as: “Skip to the VisuallyHidden section, link”
Focusable wrapper
Announced as: “Back to the section top, link”
Props
Any native prop not listed here goes to the root element unchanged.
className adds properties VisuallyHidden doesn't set (position, insets); it can't override the hidden clip or the focused look without higher specificity.
| Prop | Type | Default | Description |
|---|---|---|---|
as | "span" | "div" | "p" | "a" | "label" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "strong" | "em" | "small" | "mark" | "s" | "legend" | "code" | "kbd" | "samp" | "abbr" | "cite" | "q" | "time" | "blockquote" | "figcaption" | "caption" | "li" | "dt" | "dd" | "span" | The root element. |
focusable | boolean | false | Show the content as an overlay while it or a descendant has focus, as skip links do. Required with as="a". |
Component tokens
| Token | Copy | Description | Aliases | Light | Dark | Preview |
|---|
Accessibility
- No role of its own: the content keeps its element's semantics (span by default, or as).
- Clipped, not display: none, so it stays in the accessibility tree.
- focusable reveals it as an overlay while it or a descendant has focus (the skip-link pattern). It moves no other content; the caller places it with className.
- as="a" requires focusable, since a hidden link must show when focused. Without focusable, tabIndex can only be -1 (a programmatic focus target), so there is no invisible Tab stop. Hidden content with a focusable descendant must also be focusable, which types can't check.
- A hidden label must still be associated with its field (htmlFor). Hide a label only when the field's purpose is visible another way, such as an adjacent Search button.
- li, caption, dt and dd, and figcaption still need their parent element (ul or ol, table, dl, figure).
- Hidden emphasis (strong, em, small, mark, s) keeps its semantics, but most screen readers don't announce emphasis by default.
- The “Announced as” captions give each example's accessible name and role. Exact wording varies by screen reader.
| Key | Action |
|---|---|
| Tab | With focusable, reaches the content and reveals it. |