Keyboard Navigation Patterns — UI/UX

Keyboard Navigation Banyak user bergantung pada keyboard: pengguna screen reader, power user, orang dengan motor disabilities. Setiap UI interaktif harus bisa d

Keyboard Navigation

Banyak user bergantung pada keyboard: pengguna screen reader, power user, orang dengan motor disabilities. Setiap UI interaktif harus bisa dioperasikan sepenuhnya dengan keyboard.

Focus Management

/* Visible focus indicator — WAJIB */
:focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}

/* Jangan pernah: */
*:focus { outline: none; } /* ← ini membuat keyboard user buta */

Tab Order

Common Keyboard Patterns

// Focus trap (modal)
// Tab di elemen terakhir → kembali ke elemen pertama
function trapFocus(modal) {
  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();
      }
    }
    if (e.key === "Escape") closeModal();
  });
}

Roving Tabindex (Toolbar, Tabs)

// Hanya satu item di tab order pada satu waktu
// Arrow keys pindah fokus antar item
<div role="tablist">
  <button role="tab" tabindex="0">Tab 1</button>
  <button role="tab" tabindex="-1">Tab 2</button>
  <button role="tab" tabindex="-1">Tab 3</button>
</div>
// ArrowRight → fokus Tab 2 (tabindex="0"), Tab 1 jadi tabindex="-1"

Skip Links

<!-- Elemen pertama di body -->
<a href="#main-content" class="skip-link">
  Langsung ke konten utama
</a>
<!-- Visible on focus, hidden otherwise -->