# Keyboard Works Everywhere

**MUST** · **ID:** `interactions-keyboard-everywhere` · **Category:** interactions
**Source:** [Vercel](https://github.com/vercel-labs/agent-skills/blob/main/skills/web-design-guidelines/SKILL.md)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/interactions-keyboard-everywhere

> MUST: Full keyboard support per WAI-ARIA APG (https://www.w3.org/WAI/ARIA/apg/patterns/)

All flows are keyboard-operable and follow WAI-ARIA patterns

Every interactive element must be reachable and usable with just a keyboard. This includes navigation, forms, modals, menus, and custom controls. Follow established patterns from WAI-ARIA to ensure consistency and predictability.

## Bad — do not do this

`interactions-keyboard-everywhere-bad`

```tsx
export function KeyboardEverywhereBad() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="p-4 bg-muted rounded-lg">
        <h3 className="font-medium mb-2">Menu</h3>
        <div className="space-y-2">
          <div
            onClick={() => alert('Edit clicked')}
            className="px-3 py-2 bg-card rounded border border-border transition-colors cursor-pointer hover:bg-background"
          >
            Edit
          </div>
          <div
            onClick={() => alert('Delete clicked')}
            className="px-3 py-2 bg-card rounded border border-border transition-colors cursor-pointer hover:bg-background"
          >
            Delete
          </div>
          <div
            onClick={() => alert('Share clicked')}
            className="px-3 py-2 bg-card rounded border border-border transition-colors cursor-pointer hover:bg-background"
          >
            Share
          </div>
        </div>
      </div>
      <p className="text-xs text-error">
        Div elements can't be reached or activated via keyboard
      </p>
    </div>
  );
}
```

## Good — do this

`interactions-keyboard-everywhere-good`

```tsx
export function KeyboardEverywhereGood() {
  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="p-4 bg-muted rounded-lg">
        <h3 className="font-medium mb-2">Menu</h3>
        <div className="space-y-2" role="menu">
          <button
            onClick={() => alert('Edit clicked')}
            className="w-full text-left px-3 py-2 bg-card rounded border border-border transition-colors hover:bg-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
            role="menuitem"
          >
            Edit
          </button>
          <button
            onClick={() => alert('Delete clicked')}
            className="w-full text-left px-3 py-2 bg-card rounded border border-border transition-colors hover:bg-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
            role="menuitem"
          >
            Delete
          </button>
          <button
            onClick={() => alert('Share clicked')}
            className="w-full text-left px-3 py-2 bg-card rounded border border-border transition-colors hover:bg-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
            role="menuitem"
          >
            Share
          </button>
        </div>
      </div>
      <p className="text-xs text-success">
        Proper button elements with keyboard support and focus rings
      </p>
    </div>
  );
}
```

## References

- [WAI-ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
- [Keyboard Accessibility](https://webaim.org/techniques/keyboard/)
