Accessibility
Components ship the same accessibility posture as upstream Bootstrap — semantic markup, ARIA where the pattern needs it, keyboard support, and a visible focus ring.
Semantic by default
Components render the right native element rather than a styled <div>. Button is a
real <button type="button">; Nav items are links; form controls are real inputs
with associated labels. Native elements are focusable and operable with the keyboard
before any script runs, and assistive technology announces them correctly.
// Renders <button type="button"> — focusable and keyboard-operable out of the box.
<Button variant="primary">Save</Button>
// Navigating? Use an anchor so it reads as a link.
<Button as="a" href="/next" variant="link">Next</Button> ARIA on interactive patterns
The composite components wire the ARIA relationships the WAI-ARIA patterns call for:
- Modal / Offcanvas —
role="dialog",aria-modal, focus trapping,Escto close, and focus returned to the trigger on close. - Dropdown —
aria-expandedon the toggle, roving focus and arrow-key navigation through items. - Alert / Toast — live-region roles so updates are announced.
- Accordion, Tabs, Pagination, Breadcrumb — the expanded/selected/current state is
exposed via
aria-expanded,aria-selected, andaria-current.
Keyboard support
Every interactive component is reachable and operable from the keyboard: Tab order
follows the DOM, Enter/Space activate controls, Esc dismisses overlays, and arrow
keys move within menus, tabs, and carousels. Focus is trapped inside modal surfaces and
restored when they close.
Visible focus
Focus indicators use the --bs-focus-ring-* tokens, so keyboard focus is always
visible and you can tune it globally through the theme (see the
FocusRing helper and the
CSS variables page). Do not remove focus outlines —
override the ring tokens instead if you need a different look.
Hiding content accessibly
Use the VisuallyHidden helper to provide text for screen readers without showing it
visually — for icon-only buttons, skip links, and supplementary labels:
import { Button, VisuallyHidden, Icon } from '@metatoy/bootstrap-styled';
<Button variant="outline-secondary">
<Icon name="gear" />
<VisuallyHidden>Open settings</VisuallyHidden>
</Button> Verified against axe
The library’s test suite runs an automated accessibility harness (axe-core) across the
component set as part of its Bootstrap-parity checks, so common issues — missing labels,
invalid ARIA, insufficient roles — are caught in CI.
Automated checks catch a meaningful slice of accessibility issues but not all of them. Test with a keyboard and a screen reader, and provide accessible names for your own content (
alttext, form labels, icon-button labels).