Accessibility
Monochrome follows WAI-ARIA Authoring Practices and targets WCAG 2.2 Level AA compliance.
Standards Compliance
Every component implements the correct ARIA pattern:
Keyboard Navigation
All components are fully keyboard accessible. No mouse required.
Accordion
Key Action TabFocus next trigger Shift + TabFocus previous trigger Enter or SpaceToggle panel ArrowDownFocus next trigger ArrowUpFocus previous trigger HomeFocus first trigger EndFocus last trigger
Disabled accordion items are skipped during keyboard navigation.
Collapsible
Key Action TabFocus trigger Enter or SpaceToggle panel
Collapsible follows the WAI-ARIA disclosure pattern. It does not support arrow key navigation (only accordions do).
Tabs
Key Action TabFocus active tab, then moves to panel ArrowRight / ArrowLeftNavigate tabs (horizontal) ArrowDown / ArrowUpNavigate tabs (vertical) HomeFocus first tab EndFocus last tab Enter or SpaceActivate focused tab
Manual Activation: Monochrome uses manual activation (not automatic). Users must press Enter or Space to activate a tab after focusing it with arrow keys. This prevents accidental activation and reduces cognitive load.
Key Action TabClose all menus and move focus away Enter or SpaceOpen menu (trigger) or activate item ArrowDownNavigate to next item ArrowUpNavigate to previous item ArrowRightOpen submenu or navigate menubar ArrowLeftClose submenu or navigate menubar HomeFocus first item EndFocus last item EscapeClose current menu level Letter keysTypeahead to item starting with that letter
Typeahead: Pressing letter keys jumps to the next item whose text starts with that letter.
Keyboard vs Mouse Behavior: When opened via keyboard (Enter/Space), menus focus the first item. When opened via mouse click, focus stays on the trigger. This follows WAI-ARIA best practices.
Focus Management
Monochrome uses roving tabindex for arrow key navigation:
Only one element is in the tab order (tabindex="0")
All other navigable elements have tabindex="-1"
Arrow keys move focus without affecting the tab order
This creates a single tab stop for groups of related controls
How It Works
Accordion (Initial State)
Accordion (After ArrowDown)
< button id = "mct:accordion:faq-1" tabindex = "0" > Question 1 </ button >
< button id = "mct:accordion:faq-2" tabindex = "-1" > Question 2 </ button >
< button id = "mct:accordion:faq-3" tabindex = "-1" > Question 3 </ button >
ARIA Attributes
Monochrome manages all ARIA attributes automatically. You don’t set them manually.
Accordion
aria-expanded="true|false" — Trigger state
aria-controls="{panel-id}" — Links trigger to panel
aria-labelledby="{trigger-id}" — Labels panel with trigger
aria-disabled="true" — Disabled state (not HTML disabled)
role="region" — Panel landmark
Tabs
role="tablist" — Tab container
role="tab" — Tab buttons
role="tabpanel" — Content panels
aria-selected="true|false" — Active tab
aria-controls="{panel-id}" — Links tab to panel
aria-labelledby="{tab-id}" — Labels panel with tab
aria-orientation="horizontal|vertical" — Arrow key direction
role="menu" — Menu container
role="menubar" — Menubar container
role="menuitem" — Standard item
role="menuitemcheckbox" — Toggle item
role="menuitemradio" — Radio item
aria-haspopup="menu" — Trigger has submenu
aria-expanded="true|false" — Menu open state
aria-checked="true|false" — Checkbox/radio state
aria-disabled="true" — Disabled item
Monochrome uses aria-disabled="true", not the HTML disabled attribute. This is intentional:
Disabled menu items render as <span> to prevent click bubbling
aria-disabled keeps elements in the accessibility tree
Screen readers announce disabled state
Screen Reader Support
All components are tested with:
NVDA (Windows / Firefox)
JAWS (Windows / Chrome)
VoiceOver (macOS / Safari)
Narrator (Windows / Edge)
Announcements
Triggers announce their expanded state: “Question 1, button, collapsed”
Tabs announce selection: “Home, tab, 1 of 3, selected”
Menu items announce role: “New File, menu item”
Checkbox items announce state: “Bold, menu item checkbox, checked”
Find-in-Page Support
Monochrome uses hidden="until-found" instead of display: none. This preserves browser find-in-page (Cmd+F / Ctrl+F).
How It Works
User presses Cmd+F and searches for text inside a collapsed panel
Browser finds the text and fires a beforematch event
Monochrome’s core listens for beforematch and automatically opens the containing component
Browser scrolls to and highlights the found text
hidden="until-found" is a Baseline 2024 feature supported in all modern browsers.
Color Contrast
Monochrome is headless, so contrast is your responsibility. Follow WCAG 2.2 Level AA:
Normal text: 4.5:1 contrast ratio
Large text: 3:1 contrast ratio (18pt+ or 14pt+ bold)
UI components: 3:1 contrast ratio for interactive elements
Testing Tools
Touch and Mobile Support
All keyboard interactions work on mobile via touch:
Touch targets: Ensure buttons are at least 44×44px (WCAG 2.2 Target Size)
Menu hover intent: Safety triangles are disabled for touch (pointerType === "touch")
Scrolling: Menus close on scroll (unless scrolling inside the menu itself)
Disabled State
Disabled items are:
Marked with aria-disabled="true"
Skipped during keyboard navigation
Announced by screen readers as “disabled”
Non-interactive (cannot be clicked)
< Accordion.Item disabled >
< Accordion.Trigger > Disabled Section </ Accordion.Trigger >
< Accordion.Panel > Content </ Accordion.Panel >
</ Accordion.Item >
Best Practices
Provide visible focus indicators — Users must see where keyboard focus is
Use semantic heading levels — Accordion headers default to <h3>, but you can change via the as prop
Label regions properly — All panels are linked to their triggers via aria-labelledby
Test with keyboard only — Unplug your mouse and navigate your entire UI
Test with a screen reader — Enable VoiceOver (macOS) or NVDA (Windows) and navigate
Avoid manual ARIA — Let Monochrome manage attributes. Manual overrides can break functionality
Maintain focus order — Don’t use tabindex values other than 0 and -1
WCAG 2.2 Checklist
Level A (Required)
✅ 1.1.1 Non-text Content — Images have alt text (your responsibility)
✅ 2.1.1 Keyboard — All functionality available via keyboard
✅ 2.1.2 No Keyboard Trap — Users can navigate away with Tab or Escape
✅ 4.1.2 Name, Role, Value — All ARIA attributes correctly set
Level AA (Target)
✅ 1.4.3 Contrast (Minimum) — 4.5:1 text, 3:1 UI (your responsibility)
✅ 2.4.7 Focus Visible — Focus indicator always visible (your responsibility)
✅ 2.5.8 Target Size (Minimum) — 44×44px touch targets (your responsibility)
✅ 3.2.4 Consistent Identification — Components behave predictably
Additional Resources