Vanilla Breeze

Accessibility Utilities

Copy-paste utilities for screen-reader-only content, skip links, icon-only buttons, and 'opens in new tab' hints.

Small CSS/HTML patterns that give screen reader users what sighted users already get from visual layout. All are shipped in the core bundle or trivial to copy.

.visually-hidden

A utility class that hides content from the screen while keeping it available to assistive tech. Use it for labels, headings, and helper text that are redundant for sighted users but essential for screen reader navigation. Shipped in the core CSS — no import needed.

Icon-only button label

Icon-only controls need an accessible name. Put the label in a .visually-hidden span inside the button. Both pick the label up: sighted users see the icon, screen reader users hear “Close”.

Prefer aria-label for the simple case (<button aria-label="Close">). Reach for .visually-hidden when you want the label to be translatable by the same pipeline that handles the rest of your page content, or when the label needs to include formatted markup.

Section heading for screen reader navigation

When a section’s purpose is obvious visually but would read as unstructured to a screen reader, add a hidden heading. Screen reader users can then jump between sections with their heading-navigation shortcut.

Form legend that is not visually needed

Radio and checkbox groups need a <legend> for the <fieldset>’s accessible name. If the page already makes the group’s purpose obvious (e.g. a segmented control next to a label), hide the legend rather than leaving it off.

The utility itself

For reference (already in the bundle — you do not need to copy this):

A keyboard user tabs in from the address bar and should not have to walk through every header link before reaching the page content. A skip link — hidden until focused — gives them a one-keystroke shortcut to #main.

Markup

Place as the first focusable element in <body>. Target any element with a matching id (typically <main id="main">).

Styles

The skip link starts off-screen via the same clip technique .visually-hidden uses, then snaps into place when it receives focus. Drop this into your project CSS:

Multi-target pattern

For docs pages with several large regions (sidebar, TOC, content, etc.), ship two or more skip links in a list. Sighted keyboard users tab through them in order; screen reader users find them via the heading-navigation shortcut.

“Opens in new tab” hint

When a link opens in a new window (target="_blank") or triggers a file download, WCAG 3.2.5 says users need advance warning. Sighted users can get that from an icon; screen reader users need text.

With an icon

Without an icon

Even cleaner: always append the hint. Since it’s only audible, there is no visual cost.

Hidden form labels

Every form control needs a label. When a visible label would be redundant — a search input with a magnifying-glass icon, for instance — hide the label with .visually-hidden rather than omitting it or relying on placeholder. Placeholders vanish on input and are not a substitute.

When to reach for what

Need Use Why not the alternative
Name an icon-only button aria-label Simplest. Reach for .visually-hidden only if the label needs translation pipeline parity with body copy.
Describe an icon next to visible text aria-hidden="true" on the icon The visible text already names the control. Avoid doubling up.
Section heading for screen readers only <h2 class="visually-hidden"> aria-label on the wrapper works but screen readers read it as a label, not a navigable heading.
Hide a <legend> from sighted users .visually-hidden A fieldset without a legend has no accessible name. Styling legend with display: none breaks it.
Let keyboard users jump past nav Skip link Sectioning landmarks help screen readers but not sighted keyboard users. Both need the skip link.
  • Accessibility overview — WCAG commitment, keyboard shortcut tables, testing guidance
  • <label> — native form labeling
  • <a> — link semantics and target handling
  • tabindex — making non-focusable elements focusable (needed for skip-link targets)
  • Page shell snippet — uses .skip-link in context