Lesson 6 / 25

Focus management

Control focus order and visibility for keyboard users.

Tab order & visual focus

Focus follows HTML order by default. Never hide the outline with outline: none without a replacement. Show a clear focus indicator (border, background, glow).

Modal focus trap

When a modal opens, move focus to it and trap Tab within it until close.

// Focus trap in modal
function openModal(id) {
  const modal = document.getElementById(id);
  const focusable = modal.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const first = focusable[0];
  const last = focusable[focusable.length - 1];
  
  modal.addEventListener('keydown', (e) => {
    if (e.key === 'Tab') {
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    }
  });
  
  first.focus();
  modal.showModal();
}

Focus styling best practices

Use box-shadow, outline-offset, or background color to indicate focus. Ensure 3:1 contrast with background. Don't rely on color alone.

CSS :focus-visible

Use :focus-visible to show focus only for keyboard users, not mouse.

/* Show focus for keyboard, not mouse */
button:focus-visible {
  outline: 3px solid #10b981;
  outline-offset: 2px;
}

/* Mouse click won't show outline */
button:focus:not(:focus-visible) {
  outline: none;
}