Bagi pengguna yang tidak memakai mouse — karena keterbatasan motorik, karena mengandalkan screen reader, atau sekadar demi kecepatan — tombol Tab adalah kursor mereka. Setiap ketukan memindahkan fokus ke elemen interaktif berikutnya, dan satu-satunya cara mereka mengetahui posisi di halaman adalah indikator fokus yang kita sediakan. Chapter Outline dan :focus dan :focus-visible sudah menata ring-nya; chapter ini melihat gambar utuhnya: urutan Tab dan hubungannya dengan CSS, ring fokus yang layak di beragam latar, serta pola skip link yang wajib ada di setiap halaman bermenu.

Urutan Tab Mengikuti DOM #

Urutan fokus keyboard ditentukan urutan elemen di dalam DOM — bukan posisi visual di layar. CSS bisa memindahkan tampilan sebuah elemen ke mana saja, tetapi tidak bisa memindahkan fokusnya bersamaan:

Teknik CSSEfek visualEfek pada urutan Tab
position: absolute di akhir halamanelemen tampil di atasTab tetap menyusul urutan DOM
flex-direction: row-reversebarisan terbalikurutan Tab tetap semula
order pada item flex/gridurutan baris berubahurutan Tab tetap semula
float: rightelemen berpindah sisiurutan Tab tetap semula

Ketidaksesuaian inilah jebakannya. Property order pada Flexbox dan Grid tampak seperti solusi cepat untuk menu yang urutannya salah:

css
.nav-utama {
  display: flex;
  gap: 16px;
}

/* Tampil paling kiri, tetapi Tab tetap mengunjunginya paling akhir */
.nav-utama .tautan-masuk {
  order: -1;
}

Panduan yang jujur: order aman untuk ubin non-interaktif yang urutan bacanya bebas, dan berbahaya untuk elemen interaktif. Jika urutan visual salah, perbaiki urutan di HTML; itu satu-satunya perbaikan yang menyamakan tampilan, Tab, dan pembacaan screen reader sekaligus. Hindari juga menambalnya dengan tabindex bernilai positif — pola itu dianggap anti-pola. Demo berikut membuat konfliknya bisa dirasakan — tekan Tab berulang di dalam bingkai:

Ring Fokus yang Layak #

Ring fokus bekerja ketika memenuhi tiga syarat: terlihat, kontras, dan konsisten. Dua syarat pertama sudah dibahas — outline tidak memakan ruang dan mengikuti border-radius, sementara ambangnya mengikuti kontras non-teks 3:1 dari chapter sebelumnya. Syarat ketiga yang sering terlupa: ring harus tetap terlihat di semua latar yang dipakai halaman, termasuk header gelap:

css
.tautan-nav {
  color: #1f6f54;
}

.tautan-nav:focus-visible {
  outline: 2px solid #1f6f54;
  outline-offset: 2px;
}

/* Latar gelap butuh ring terang, bukan ring gelap yang sama */
.tautan-nav-di-latar-gelap:focus-visible {
  outline-color: #f4b942;
}

Demo berikut menempatkan tautan yang sama pada dua latar — tekan Tab di dalam bingkai:

Efek hover juga sebaiknya dipasangkan dengan fokus: gabungkan :hover dan :focus-visible dalam satu selector group agar pengguna keyboard menerima umpan balik yang sama dengan pengguna mouse.

Pengguna keyboard tanpa skip link harus men-Tab melewati seluruh menu di setiap halaman — dua puluh tautan nav berarti dua puluh ketukan sebelum sampai ke isi. Skip link adalah tautan pertama di halaman yang melompat langsung ke konten utama. Pola standarnya: tersembunyi dari tampilan sampai menerima fokus, lalu muncul di tepi atas:

html
<body>
  <a class="skip-link" href="#konten-utama">Lewati navigasi, menuju konten utama</a>
  <nav class="nav-utama" aria-label="Navigasi utama">
    <!-- daftar tautan menu -->
  </nav>
  <main id="konten-utama" tabindex="-1">
    <h2>Selamat datang</h2>
  </main>
</body>
css
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  transform: translateY(-150%); /* tersembunyi di atas layar */
  padding: 10px 16px;
  background-color: #1f6f54;
  color: #fdfaf3;
  border-radius: 0 0 10px 10px;
  text-decoration: none;
  z-index: 10;
}

.skip-link:focus-visible {
  transform: translateY(0); /* muncul saat menerima fokus keyboard */
}

#konten-utama:focus {
  outline: 2px solid #1f6f54;
  outline-offset: 4px;
}

Mari kita telaah keputusan pentingnya:

  1. Urutan DOM. Skip link berada sebagai elemen pertama di dalam <body>, sehingga satu ketukan Tab dari awal halaman langsung menemukannya.
  2. transform: translateY(-150%). Elemen tetap ada di DOM dan bisa difokuskan, hanya digeser ke atas layar. Teknik display: none atau visibility: hidden justru membuatnya tidak bisa difokuskan sama sekali.
  3. :focus-visible mengembalikannya. Begitu menerima fokus keyboard, tautan turun ke posisi terlihat. Pemakaian transform juga menjaga animasi tetap murah.
  4. tabindex="-1" pada target. Elemen <main> bukan elemen interaktif; atribut ini mengizinkannya menerima fokus programatik, sehingga setelah tautan diklik fokus benar-benar pindah — bukan sekadar layar menggulir sementara fokus tertinggal di atas.

Demo berikut menempatkan skip link sebagai elemen pertama, diikuti tiga tautan nav, lalu konten utama. Klik dulu di dalam area demo agar bingkai menerima fokus, lalu tekan Tab satu kali:

Pada halaman nyata, tiga tautan nav itu bisa berupa tiga puluh — dan skip link tetap menempuhnya dalam satu ketukan.

Kesalahan Umum #

KesalahanAkibatnyaPerbaikannya
Menyembunyikan skip link dengan display: nonetautan tidak bisa difokuskan, pola gagal totalgeser dengan transform atau clip-path, bukan hapus dari akses
Meluruskan urutan visual dengan order atau tabindex positifTab dan tampilan saling bertentanganperbaiki urutan elemen di HTML
Ring fokus satu warna untuk semua latarring tak terlihat di header atau footer berlawanan warnasediakan outline-color terang untuk latar gelap
Skip link menunjuk elemen tanpa tabindex="-1"layar menggulir, tetapi fokus tertinggal di atastambahkan tabindex="-1" pada target lompatan

Ringkasan #

Urutan Tab mengikuti DOM, sehingga CSS yang memindah tampilan — terutama property order — bisa menciptakan halaman yang terlihat satu cara dan dinavigasi dengan cara lain; perbaikan yang benar ada di urutan HTML. Ring fokus yang layak terlihat, kontras, dan konsisten di semua latar, dan skip link memberi pengguna keyboard jalan pintas yang wajib ada. Chapter berikutnya berpindah dari fokus ke gerakan: menyempurnakan penghormatan terhadap prefers-reduced-motion, dari pola global sampai scroll halus dan parallax.