Skip to content

Focus ring draft v0.2.0

The one visible focus indicator every focusable component shows on keyboard focus.

People who move through an interface with a keyboard, a switch or another assistive input need to see which component will receive their next action. The focus ring is the system's single answer: the same solid ring, in the same color, at the same distance, around every focusable component, on every surface and in every mode. Components do not design their own focus indicator; they draw this one from their focus-visible tokens, which alias the tokens below.

Tokens

Semantic tokens owned by the foundation (tokens in packages/components/specs/foundations/focus.spec.json). They live in packages/tokens/src/semantic/ (recreated from the Figma library) or tokens/additions/semantic/ (added by the design system), with their other values in tokens/modes/, tokens/additions/modes/ and tokens/platforms/.

Token Type Value Resolved CSS
color.focus.ring
Focus indicator color shared by every interactive component.
color {brand.light.600}
light #175DD6
dark #9EE7FA
--color-focus-ring
focus.ring.width
Focus ring of every component: the strong focus of the stroke scale, thick enough for WCAG 2.4.13 Focus Appearance (AAA).
dimension {stroke-width.lg}
2.4px
--focus-ring-width
focus.ring.offset dimension {space.4}
4px
--focus-ring-offset

Components following it

Derived from the component tokens aliasing the foundation's tokens. Every component with a focusable role must follow it (pnpm validate).

ComponentComponent tokens aliasing the foundation
Accordion
  • accordion.trigger.outline-width.focus-visible → {focus.ring.width}
  • accordion.trigger.outline-offset.focus-visible → {focus.ring.offset}
  • accordion.trigger.outline-color.focus-visible → {color.focus.ring}
Breadcrumb
  • breadcrumb.link.outline-width.focus-visible → {focus.ring.width}
  • breadcrumb.link.outline-offset.focus-visible → {focus.ring.offset}
  • breadcrumb.link.outline-color.focus-visible → {color.focus.ring}
Button
  • button.container.outline-width.focus-visible → {focus.ring.width}
  • button.container.outline-offset.focus-visible → {focus.ring.offset}
  • button.container.outline-color.focus-visible → {color.focus.ring}
Checkbox group
  • checkbox-group.control.outline-width.focus-visible → {focus.ring.width}
  • checkbox-group.control.outline-offset.focus-visible → {focus.ring.offset}
  • checkbox-group.control.outline-color.focus-visible → {color.focus.ring}
Checkbox
  • checkbox.control.outline-width.focus-visible → {focus.ring.width}
  • checkbox.control.outline-offset.focus-visible → {focus.ring.offset}
  • checkbox.control.outline-color.focus-visible → {color.focus.ring}
Dropdown
  • dropdown.item.outline-width.focus-visible → {focus.ring.width}
  • dropdown.item.outline-offset.focus-visible → {focus.ring.offset}
  • dropdown.item.outline-color.focus-visible → {color.focus.ring}
Icon button
  • icon-button.container.outline-width.focus-visible → {focus.ring.width}
  • icon-button.container.outline-offset.focus-visible → {focus.ring.offset}
  • icon-button.container.outline-color.focus-visible → {color.focus.ring}
Number field
  • number-field.control.outline-width.focus-visible → {focus.ring.width}
  • number-field.control.outline-offset.focus-visible → {focus.ring.offset}
  • number-field.control.outline-color.focus-visible → {color.focus.ring}
Pagination
  • pagination.link.outline-width.focus-visible → {focus.ring.width}
  • pagination.link.outline-offset.focus-visible → {focus.ring.offset}
  • pagination.link.outline-color.focus-visible → {color.focus.ring}
Radio group
  • radio-group.control.outline-width.focus-visible → {focus.ring.width}
  • radio-group.control.outline-offset.focus-visible → {focus.ring.offset}
  • radio-group.control.outline-color.focus-visible → {color.focus.ring}
Search field
  • search-field.control.outline-width.focus-visible → {focus.ring.width}
  • search-field.control.outline-offset.focus-visible → {focus.ring.offset}
  • search-field.control.outline-color.focus-visible → {color.focus.ring}
Select
  • select.control.outline-width.focus-visible → {focus.ring.width}
  • select.control.outline-offset.focus-visible → {focus.ring.offset}
  • select.control.outline-color.focus-visible → {color.focus.ring}
Slider
  • slider.control.outline-width.focus-visible → {focus.ring.width}
  • slider.control.outline-offset.focus-visible → {focus.ring.offset}
  • slider.control.outline-color.focus-visible → {color.focus.ring}
Switch
  • switch.control.outline-width.focus-visible → {focus.ring.width}
  • switch.control.outline-offset.focus-visible → {focus.ring.offset}
  • switch.control.outline-color.focus-visible → {color.focus.ring}
Text field
  • text-field.control.outline-width.focus-visible → {focus.ring.width}
  • text-field.control.outline-offset.focus-visible → {focus.ring.offset}
  • text-field.control.outline-color.focus-visible → {color.focus.ring}
Textarea
  • textarea.control.outline-width.focus-visible → {focus.ring.width}
  • textarea.control.outline-offset.focus-visible → {focus.ring.offset}
  • textarea.control.outline-color.focus-visible → {color.focus.ring}