Skip to content

Lesson 5 of 6

Keyboard and accessibility

Make every control understandable without a mouse or a pair of eyes.

Give controls a name

Visible text is usually the best name because everyone can see it. Use Label with fields, and use aria-label for an icon-only button or an unnamed list. A screen reader should be able to say what the focused thing does.

Add thistsx
<TextField>
  <Label>Email</Label>
  <Input name="email" />
</TextField>

<Button aria-label="Close">×</Button>

Keep familiar key symbols

Enter and Space activate buttons. Arrow keys move through menus, list boxes, radio groups, and tabs; Escape closes overlays. Let the component handle these familiar keys instead of giving them surprising new jobs.

Add thistsx
<Menu>
  <MenuTrigger>Actions</MenuTrigger>
  <MenuPopover>
    <MenuList aria-label="Actions">...</MenuList>
  </MenuPopover>
</Menu>

Protect focus and explain errors

When a dialog closes, focus should return to the trigger that opened it. Keep a visible focus ring so people can follow that movement. Put Description and FieldError next to a field so help and validation feedback are connected to the input.

Add thistsx
<TextField invalid>
  <Label>Email</Label>
  <Input name="email" />
  <FieldError>Enter a valid email.</FieldError>
</TextField>