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 CSS | Efek visual | Efek pada urutan Tab |
|---|---|---|
position: absolute di akhir halaman | elemen tampil di atas | Tab tetap menyusul urutan DOM |
flex-direction: row-reverse | barisan terbalik | urutan Tab tetap semula |
order pada item flex/grid | urutan baris berubah | urutan Tab tetap semula |
float: right | elemen berpindah sisi | urutan Tab tetap semula |
Ketidaksesuaian inilah jebakannya. Property order pada Flexbox dan Grid tampak seperti solusi cepat untuk menu yang urutannya salah:
.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:
.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.
Skip Link: Jalan Pintas ke Konten Utama #
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:
<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>.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:
- Urutan DOM. Skip link berada sebagai elemen pertama di dalam
<body>, sehingga satu ketukan Tab dari awal halaman langsung menemukannya. transform: translateY(-150%). Elemen tetap ada di DOM dan bisa difokuskan, hanya digeser ke atas layar. Teknikdisplay: noneatauvisibility: hiddenjustru membuatnya tidak bisa difokuskan sama sekali.:focus-visiblemengembalikannya. Begitu menerima fokus keyboard, tautan turun ke posisi terlihat. Pemakaiantransformjuga menjaga animasi tetap murah.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 #
| Kesalahan | Akibatnya | Perbaikannya |
|---|---|---|
Menyembunyikan skip link dengan display: none | tautan tidak bisa difokuskan, pola gagal total | geser dengan transform atau clip-path, bukan hapus dari akses |
Meluruskan urutan visual dengan order atau tabindex positif | Tab dan tampilan saling bertentangan | perbaiki urutan elemen di HTML |
| Ring fokus satu warna untuk semua latar | ring tak terlihat di header atau footer berlawanan warna | sediakan outline-color terang untuk latar gelap |
Skip link menunjuk elemen tanpa tabindex="-1" | layar menggulir, tetapi fokus tertinggal di atas | tambahkan 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.