Keyboard Navigation

How every Byteion component supports keyboard-first interaction.

Overview

Many users rely on keyboard navigation, including screen reader users, people with motor impairments, switch-device users, and power users. Every interactive Byteion component should be reachable with Tab, operable with activation keys, and dismissible with Escape where applicable. If a component requires a mouse, it is not complete.

Keyboard interaction contract

Interactive Byteion components should follow these rules:

  • Be reachable with Tab when they are interactive
  • Be skipped by Tab when disabled or hidden
  • Show a visible focus state
  • Use native keyboard behaviour where possible
  • Support expected activation keys
  • Close dismissible overlays with Escape
  • Keep focus inside modal / drawer overlays while open
  • Restore focus to the trigger after closing overlays
  • Preserve logical focus order matching the visual reading order

Core key table

KeyExpected behaviour
TabMove to the next focusable control
Shift+TabMove to the previous focusable control
EnterActivate buttons, links, selected menu items, or selected tabs where appropriate
SpaceActivate buttons, checkboxes, toggles, and selected menu items where appropriate
EscapeClose dismissible overlays such as modals, drawers, dropdowns, popovers, and menus
Arrow keysMove within composite widgets such as tabs, menus, radio groups, listboxes, and roving-tabindex groups
Home / EndMove to first / last item in tab lists, menus, or listbox-like widgets where supported

Use native elements whenever possible so browsers provide correct keyboard behaviour automatically.

Component-specific keyboard behaviour

Component Keyboard behaviour
ButtonEnter and Space activate. Disabled buttons are not interactive.
LinkEnter follows the link. Use links for navigation, not actions.
Input / TextareaNative typing, selection, and focus behaviour. Labels and errors must be connected.
Checkbox / SwitchSpace toggles state. State must be visible and announced.
Select / ComboboxUse native select where possible; custom comboboxes need arrow navigation and clear expanded state.
Modal / DialogFocus moves inside on open, Tab cycles inside, Escape closes, focus returns to trigger.
DrawerSame overlay rules as modal when it blocks the page.
Dropdown / MenuTrigger opens with Enter / Space, arrow keys move between items, Escape closes, focus returns.
TabsArrow keys move between tabs, Home / End jump, Enter / Space activates if activation is manual.
TooltipAppears on focus / hover, does not trap focus, dismisses on Escape if interactive behaviour is present.
Toast / AlertShould not steal focus unless immediate action is required.
Table / DataTableNative table reading order; interactive controls inside rows remain reachable.

Focus management

  • Focus should move intentionally when overlays open
  • Modal / drawer focus should be trapped while open
  • Focus should return to the trigger after close
  • Background content should not be reachable while modal overlays are active
  • Do not move focus unexpectedly during normal page updates
  • Use tabindex="-1" for programmatic focus targets such as dialog containers or headings
  • Avoid tabindex="0" unless creating a valid custom interactive pattern
  • Never use tabindex greater than 0

Practical examples

Modal keyboard flow

  1. User tabs to the trigger button
  2. Enter or Space opens the modal
  3. Focus moves to the first useful control or the dialog container
  4. Tab and Shift+Tab cycle inside the modal
  5. Escape closes the modal
  6. Focus returns to the original trigger

Dropdown keyboard flow

  1. User tabs to the trigger
  2. Enter or Space opens the dropdown
  3. Arrow keys move between menu items
  4. Enter activates the focused item
  5. Escape closes the dropdown and returns focus

Tabs keyboard flow

  1. User tabs to the tab list
  2. Left / Right arrows move between tabs
  3. Home / End jumps to first / last tab
  4. Enter or Space activates the focused tab if activation is manual
  5. Tab moves into the active panel

Custom control guidance

Prefer native controls first. If it behaves like a button, use <button>. If it navigates, use <a href="">. Use tabindex="0" only when a custom interactive pattern is unavoidable, and only after adding the correct role, keyboard handlers, state attributes, and visible focus styles.

Keyboard testing checklist

  • Complete a full workflow using only keyboard
  • Test Tab and Shift+Tab order
  • Test Enter and Space activation
  • Test Escape dismissal for overlays
  • Test arrow-key behaviour in tabs, menus, radio groups, and listbox-like widgets
  • Test focus trap and focus return for modals / drawers
  • Test visible focus in light and dark mode
  • Inspect document.activeElement while debugging
  • Run automated accessibility checks, but verify manually

Do and Don't

Do

  • Use native interactive elements first
  • Keep logical DOM order
  • Show visible focus states
  • Use tabindex="-1" for programmatic focus when needed
  • Return focus after overlays close
  • Test every interactive component with keyboard only

Don't

  • Use <div onClick> for buttons
  • Use tabindex greater than 0
  • Hide focus indicators
  • Trap users without Escape or close controls
  • Move focus unexpectedly after every render
  • Rely on hover-only interactions

Developer tips

• Disconnect your mouse and complete a real workflow — forms, modals, dropdowns, tabs. • Use document.activeElement in DevTools to see which element currently has focus. • Run screen-reader smoke checks with VoiceOver (macOS) or NVDA (Windows). • Byteion JS handles supported keyboard patterns for data-bi-* components, but custom compositions still need manual testing. • Keyboard testing should include forms, modals, dropdowns, tabs, sidebars, data tables, and settings pages. • Test in both light and dark mode — focus indicators must be visible on all surfaces.

Unlock Premium Patterns

Get access to copy-paste ready Pro blocks, SaaS templates, and advanced component patterns.

Explore Pro Components