Skip to content

Design system

Documentation

DesignFoundations / Accessibility

Foundations / Accessibility

Stable

Accessibility

Accessibility is part of the component contract: a person must be able to see, reach, understand, and recover from every state.

On this page

Focus

Keyboard focus stays visible on both theme canvases and uses the shared ring tokens. Focus should not depend on hover or on a change of color alone.

TokenValueContract
--focus-ring-width3pxVisible against the control and its surrounding surface.
--focus-ring-offset2pxSeparates focus from the component edge.
--focus-ring-colorSemantic brand focusRemains recognizable in light and dark modes.

Contrast

Check the real light and dark surfaces, not only isolated swatches. Status colors include text, background, and border roles so color is not the only signal.

Primary copyReadable body text

--color-text-primary on --color-bg-surface

Supporting copySupporting text

Use only where the surrounding context carries the hierarchy.

Do notDisabled-looking text

Do not use disabled contrast for content that a person still needs to read.

Scrollbars

The document viewport keeps the platform scrollbar. Bounded regions opt into scrollbar-hover-reveal from packages/ui/src/styles/base.css: the thumb is visually hidden until pointer hover, keyboard focus within the region, or active interaction.

PartContractReason
Track--color-scrollbar-track (transparent)Avoids a bright rail that competes with content.
Thumb--color-scrollbar-thumb, rounded, thinStays quiet by default and appears when the region is being explored.
InteractionHover, :focus-within, or active stateReveals the handle without making every rail a permanent visual.
Touch / gutterVisible thumb / scrollbar-gutter: stablePreserves discoverability on touch and prevents layout shifts.
High contrastscrollbar-color: autoLets the operating system restore its accessible colors.
  • Keep a scroll region bounded and let it scroll; do not clip content just to remove the scrollbar.
  • Do not communicate a state only through thumb color. The region still needs a usable size, native scrolling, and clear surrounding context.
  • Check nested regions, keyboard scrolling, touch input, zoom to 200%, and forced-colors mode before shipping.

Labels and errors

  • Every control has a visible label or a concise accessible name; icon-only actions use aria-label.
  • Errors identify the field, explain what needs to change, and are linked with aria-describedby when the component supports it.
  • Do not communicate status with color alone; pair it with text, an icon, or a change in structure.

Interaction checklist

Before shipping

Tab through the route, activate controls with Enter/Space, test Escape for overlays, zoom to 200%, and enable reduced motion.

Common regressions

Hidden focus, clipped scroll regions, hover-only instructions, unlabeled icon buttons, and errors announced only by color.

Use the Colors, Sizing, and Motion pages together when reviewing a component.