Accessibility

Vanilla Breeze is built with accessibility as a core principle, not an afterthought. This guide covers the accessibility features built into components and how to use them effectively.

Our Commitment

Vanilla Breeze targets WCAG 2.1 Level AA compliance. All components are designed to be:

Report Accessibility Issues

Found an accessibility problem? Please open an issue on GitHub with the label "accessibility". We take these reports seriously and prioritize fixes.

Keyboard Navigation

All interactive components support full keyboard navigation. Here are the patterns used:

Global Keys

Key Action
Tab Move focus to next focusable element
Shift + Tab Move focus to previous focusable element
Enter / Space Activate focused button or link
Escape Close dialogs, dropdowns, and popovers

Component-Specific Keys

Tabs (tabs-wc)

Key Action
Arrow Left / Arrow Right Navigate between tabs (horizontal)
Arrow Up / Arrow Down Navigate between tabs (vertical orientation)
Home Go to first tab
End Go to last tab

Accordion (accordion-wc)

Key Action
Enter / Space Toggle accordion section
Arrow Down Move focus to next accordion header
Arrow Up Move focus to previous accordion header
Home Move focus to first accordion header
End Move focus to last accordion header

Dropdown (drop-down)

Key Action
Enter / Space Open dropdown, activate menu item
Arrow Down Open dropdown / move to next item
Arrow Up Move to previous item
Escape Close dropdown

Focus Management

Vanilla Breeze components manage focus appropriately:

ARIA Patterns

Vanilla Breeze follows established ARIA patterns from the ARIA Authoring Practices Guide (APG).

Component ARIA Roles

Every interactive web component in Vanilla Breeze manages its own ARIA roles and states internally. The table below shows what each component handles for you and what you need to provide yourself.

Component Pattern Roles & States (managed internally) Developer provides
tabs-wc Tabs role="tablist|tab|tabpanel", aria-selected, aria-controls, aria-labelledby
accordion-wc Accordion role="region", aria-expanded, aria-controls, aria-labelledby
combo-box Combobox role="combobox|listbox|option", aria-expanded, aria-autocomplete, aria-controls, aria-selected, aria-activedescendant. With [data-multiple]: adds aria-multiselectable, aria-live <input> + <ul> with <li data-value> items
drop-down Menu Button role="menu|menuitem|separator", aria-haspopup, aria-expanded, aria-controls Trigger button + <menu> with items
context-menu Menu role="menu|menuitem|separator|presentation" Element with data-trigger + <menu>
tool-tip Tooltip role="tooltip", popover="hint", aria-describedby Trigger element as first child
toast-wc Alert role="region|alert", aria-live="polite", aria-label="Notifications"
carousel-wc Carousel role="region|group|tablist|tab", aria-roledescription="carousel|slide", aria-selected, aria-live, aria-label Slide content as children. Optional: aria-label
data-table Grid aria-sort, aria-expanded, aria-hidden, aria-current="page" Standard <table> markup + data-sort on sortable headers
command-palette Listbox role="listbox|option|presentation", aria-label <command-group> and <command-item> elements
site-search Dialog + Listbox role="dialog|listbox|option", aria-haspopup, aria-expanded, aria-autocomplete, aria-label
split-surface Window Splitter role="separator", aria-orientation, aria-valuenow, aria-valuemin, aria-valuemax, aria-label Two child panels
star-rating Radio Group / Image role="img" (readonly), aria-label (e.g. "Rating: 4 out of 5")
slide-accept Slider role="slider", aria-valuenow, aria-valuemin, aria-valuemax, aria-label
dialog Modal Dialog Native <dialog> semantics via showModal() aria-labelledby or aria-label

Live Regions

Dynamic content changes are announced to screen readers using ARIA live regions:

<!-- Polite: announced when user is idle --> <div aria-live="polite"> Loading complete. 42 results found. </div> <!-- Assertive: announced immediately (use sparingly) --> <div role="alert"> Error: Please fix the form errors before submitting. </div> <!-- Status: for status updates --> <div role="status"> Saving... </div>

Labels and Descriptions

Always provide accessible names for interactive elements:

<!-- Visible label (preferred) --> <label for="email">Email address</label> <input type="email" id="email" /> <!-- aria-label for icon-only buttons --> <button aria-label="Close dialog"> <icon-wc name="x"></icon-wc> </button> <!-- aria-labelledby for complex labels --> <section aria-labelledby="section-title"> <h2 id="section-title">User Settings</h2> ... </section> <!-- aria-describedby for additional context --> <input type="password" aria-describedby="password-hint" /> <p id="password-hint">Must be at least 8 characters</p>

Color and Contrast

Vanilla Breeze design tokens are designed to meet WCAG contrast requirements.

Contrast Ratios

WCAG 2.1 AA requires:

Built-in Contrast

The semantic color tokens maintain appropriate contrast in both light and dark modes:

/* These automatically meet contrast requirements */ color: var(--color-text); /* Primary text */ color: var(--color-text-muted); /* Secondary text */ background: var(--color-surface); /* Backgrounds */ /* Interactive states maintain contrast */ background: var(--color-interactive); background: var(--color-interactive-hover);

Don't Rely on Color Alone

Color should never be the only way to convey information:

Good: Error state uses color, icon, and text

Please enter a valid email address

Good: Links are underlined, not just colored

Visit our documentation for more information.

Testing Contrast

Tools to verify contrast:

Accessibility Themes

For users who need enhanced contrast, Vanilla Breeze provides dedicated accessibility themes:

High Contrast

WCAG AAA (7:1+) contrast ratios with enhanced focus indicators.

Large Text

25% larger fonts with 44px touch targets.

Dyslexia-Friendly

Atkinson Hyperlegible font with optimized spacing.

These themes are composable - combine them with any decorative theme: data-theme="forest a11y-high-contrast"

Motion and Animation

Animations can cause discomfort for users with vestibular disorders. Vanilla Breeze respects user preferences.

Respecting prefers-reduced-motion

All animations in Vanilla Breeze check the user's motion preference:

/* Animations are enabled by default */ .accordion-content { transition: height var(--duration-normal) var(--ease-default); } /* Disabled when user prefers reduced motion */ @media (prefers-reduced-motion: reduce) { .accordion-content { transition: none; } }

What Gets Reduced

Testing Reduced Motion

To test reduced motion in your browser:

  1. Open DevTools
  2. Press Cmd/Ctrl + Shift + P to open command palette
  3. Type "reduced motion" and select "Emulate CSS prefers-reduced-motion: reduce"

Accessible Forms

Forms are critical for accessibility. Vanilla Breeze provides patterns that work for everyone.

The form-field Component

The <form-field> custom element ensures proper label association and error handling:

<form-field> <label for="username">Username</label> <input type="text" id="username" required aria-describedby="username-hint" /> <span id="username-hint" class="help"> Letters and numbers only, 3-20 characters </span> </form-field>

Error States

When validation fails, provide clear feedback:

<form-field> <label for="email">Email</label> <input type="email" id="email" required aria-invalid="true" aria-describedby="email-error" /> <span id="email-error" class="error" role="alert"> Please enter a valid email address </span> </form-field>

Form Best Practices

Contact Information We'll never share your email

Required fields

Testing Accessibility

Regular testing helps catch issues early. Use a combination of automated and manual testing.

Automated Testing

Tools that catch common issues:

Manual Testing Checklist

Screen Reader Testing

Test with actual screen readers:

Platform Screen Reader Browser Pairing
macOS / iOS VoiceOver (built-in) Safari
Windows NVDA (free) Firefox or Chrome
Windows JAWS Chrome
Android TalkBack (built-in) Chrome

Quick VoiceOver Test (macOS)

  1. Press Cmd + F5 to enable VoiceOver
  2. Use Ctrl + Option + Arrow keys to navigate
  3. Listen for meaningful announcements
  4. Press Cmd + F5 again to disable

Resources

Learn more about web accessibility:

ARIA Authoring Practices

Official patterns and examples from W3C.

WCAG Quick Reference

Filterable guide to WCAG criteria.

WebAIM

Articles, tools, and training resources.

The A11Y Project

Community-driven accessibility resources.