Skip to content
Star on GitHub
DocsAccessibility
Style
Accent
Sound

Built by DesignMe, free to use under the MIT licence.

Expert design and dev support for startups and enterprises.

Book a call

Accessibility

What the components do for people using a keyboard, a screen reader, a touch screen or reduced motion, and where they still fall short.

Roles and labels

Components use the ARIA pattern that fits what they do. For example:

PatternRoles and statesFor example
MenusA menu of menuitem rows. The button that opens one reports aria-expandedButtons
Lists you pick fromA listbox of option rows. The search box that drives one is a comboboxCommand palette, Country select
A single choiceA radiogroupDecision prompt
On or off settingsA switch with aria-checkedAgent settings
Tabstablist, tab and aria-selectedCode viewer, Thread panel, Segmented control
Slidersaria-valuenow and aria-valuetextDesign tuner
File treesA tree of treeitem rowsFile explorer
PopoversA labelled dialog, like the calendarDate picker, Citation hover card
Toggle and icon buttonsToggles report their state with aria-pressed. Icon-only buttons have a labelButtons, Line chart

Live updates

Agent work changes while you watch. The parts that change are aria-live="polite" regions, so the change is read out: Status pill, the thread above Composer, the message line of Context meter, the thread in Comments and the month in Date picker.

Decorative motion, like status glyphs and the wires of a canvas, is aria-hidden, so screen readers hear the words, not the animation.

Keyboard

KeysWhat they doWhere
EscCloses menus and popoversComposer, Date picker
EscAlso returns focus to the button or field that opened themButtons, Country select, Date picker
EnterSpace↓Open a menu with the focus on its picked or first item; ↑ opens it on its lastButtons, Profile menu
TabCloses a menu and moves onButtons, Profile menu
↑↓←→Move through lists, menus and toolbars, wrapping at the endsCommand palette, Country select, Answer action bar
HomeEndGo to the first and last item of a menuButtons, Profile menu
←→↑↓In the date pickers, move a day or a weekDate picker, Date range picker
HomeEndGo to the start and end of the weekDate picker, Date range picker
Page UpPage DownMove a month, or a year with ShiftDate picker, Date range picker
1to9Pick an optionDecision prompt

Focus from the keyboard shows as one 2px ring in --focus (--dm-focus in React), a grey that reaches 3:1 on the page: an outline 2px outside the control, or a 2px ring drawn with box-shadow where an outline would be cut off. It uses :focus-visible, so a click or a tap on a button doesn't show it. Fields take no ring: their dimmed grey edge steps up to that same grey while they have the focus, and goes back once you leave them.

Most components work fully with a keyboard. A few, like Kanban board and File explorer, are still getting their keyboard support.

Reduced motion

When the device asks for less motion (prefers-reduced-motion: reduce), the components cut it in two places:

  • In the CSS

    The shared CSS cuts every CSS animation and transition inside the components to almost nothing.

  • In the scripts

    The HTML version reads REDUCE, which the core keeps in step with the same setting as it changes, so turning it on or off takes effect without a reload, and turning it on finishes what a script is animating. React components that animate from script use the useReducedMotion() hook from lib/hooks.ts, which follows the setting live too.

Count-ups finish at once, rows move without gliding, and the content still changes.

Touch screens

  • Tap areas

    On a touch screen (pointer: coarse) every button, link, tab, switch and checkbox gets a tap area of at least 40px square, centred on it: a clear ::before (or ::after, where the component already draws with its ::before) from the shared CSS, so how it looks doesn't change. A list or strip that scrolls can cut one off at its own edges.

  • Close neighbours

    Where two controls sit closer than that, a script in the core shrinks both tap areas evenly towards the gap between them, so a tap lands on the control nearest to it. It is fitHits in core.js, and lib/hits.ts in React, which every component imports.

  • Hover

    Hover styles only apply with a mouse (@media (hover:hover) and (pointer:fine)), so a tap never leaves one stuck on a phone.

Contrast

  • Text and marks

    The accent has separate roles for fills, text and marks. Text in the accent aims for 4.5:1 and marks for 3:1, on the surface and on the grey chips and tinted rows they sit on. See Theming.

  • A light accent

    Blueprint's lime is too light for text on white, so in light mode accent text uses the ink colour and marks a darker lime.

  • Edges

    An off switch and an empty box are drawn in a grey that holds 3:1 against the surface. An accent fill keeps a thin edge in the mark colour, so a light accent still has an outline.

For each component

Every component's page lists what it does under About, then Accessibility. Its Markdown copy has the same list. These notes describe what the code does. Check your product with your own content and assistive technology too.

This page as Markdown: accessibility.md