Membangun navigasi utama untuk {i>website

Tutorial ini menjelaskan cara membuat navigasi utama yang dapat diakses dari sebuah {i>website<i}. Anda akan mempelajari HTML semantik, aksesibilitas, dan bagaimana penggunaan atribut ARIA terkadang dapat lebih membahayakan daripada tidak baik.

Manuel Matuzović
Manuel Matuzović

Ada banyak cara untuk membangun navigasi utama {i>website<i}, dalam hal gaya, fungsionalitas, dan markup yang mendasari serta informasi semantik. Jika implementasinya terlalu minimalis, ia akan berfungsi untuk sebagian besar orang, tetapi pengalaman pengguna (UX) mungkin tidak terlalu bagus. Jika dibuat berlebihan, bisa membingungkan pengguna atau bahkan menghambat mereka untuk mengaksesnya sama sekali.

Untuk sebagian besar {i>website<i}, Anda ingin membangun sesuatu yang tidak terlalu sederhana, juga tidak terlalu rumit.

Membangun lapisan demi lapisan

Dalam tutorial ini, Anda akan mulai dengan penyiapan dasar dan menambahkan fitur lapisan demi lapisan hingga ke titik di mana Anda menyediakan informasi, gaya visual, dan fungsionalitas secukupnya untuk menyenangkan sebagian besar pengguna. Untuk mencapainya, Anda memanfaatkan prinsip progressive enhancement, yang menyatakan bahwa Anda memulai dengan solusi yang paling mendasar dan andal, lalu secara bertahap menambahkan lapisan fungsionalitas. Jika satu lapisan gagal berfungsi karena alasan tertentu, navigasi akan tetap berfungsi karena akan kembali ke lapisan yang mendasarinya dengan baik.

Struktur dasar

Untuk navigasi dasar, Anda memerlukan dua hal: elemen <a> dan beberapa baris CSS untuk meningkatkan gaya default dan tata letak link Anda.

<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Define variables for your colors */
:root {
  --color-shades-dark: rgb(25, 25, 25);
}

/* Use the alternative box model
Details: <https://web.dev/learn/css/box-model/> */
*{
  box-sizing: border-box;
}

/* Basic font styling */
body {
  font-family: Segoe UI, system-ui, -apple-system, sans-serif;
  font-size: 1.6rem;
}

/* Link styling */
a {
  --text-color: var(--color-shades-dark);
  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  display: inline-block;
  margin-block-end: 0.5rem; /* See note at the bottom of this chapter */
  margin-inline-end: 0.5rem;
  padding: 0.1rem;
  text-decoration: none;
}

/* Change the border-color on :hover and :focus */
a:where(:hover, :focus) {
  --border-color: var(--text-color);
}
Lihat Langkah 1: HTML dan CSS Dasar" di CodePen.

Ini berfungsi dengan baik untuk sebagian besar pengguna, tidak peduli bagaimana cara mereka mengakses situs. Navigasi dapat diakses dengan mouse, keyboard, perangkat sentuh, atau pembaca layar, tetapi masih ada ruang untuk peningkatan. Anda dapat meningkatkan pengalaman dengan memperluas pola dasar ini dengan fungsi dan informasi tambahan.

Berikut tindakan yang dapat Anda lakukan:

  • Tandai halaman yang aktif.
  • Umumkan jumlah item kepada pengguna pembaca layar.
  • Tambahkan penanda dan izinkan pengguna pembaca layar mengakses navigasi langsung menggunakan pintasan.
  • Menyembunyikan navigasi di area pandang yang sempit.
  • Tingkatkan gaya fokus.

Menyoroti halaman yang aktif

Untuk menandai halaman yang aktif, Anda dapat menambahkan kelas ke link yang sesuai.

<a href="/about-us" class="active-page">About us</a>

Masalah dengan pendekatan ini adalah bahwa cara ini menyampaikan informasi tautan mana yang aktif sepenuhnya secara visual. Pengguna pembaca layar tunanetra tidak dapat membedakan antara halaman aktif dan halaman lain. Untungnya, standar Accessible Rich Internet Applications (ARIA) menawarkan cara untuk menyampaikan informasi ini secara semantik. Gunakan atribut dan nilai aria-current=&quot;page&quot;, bukan class.

aria-current (status) menunjukkan elemen yang mewakili item saat ini dalam penampung atau kumpulan elemen terkait. Token halaman yang digunakan untuk menunjukkan link dalam kumpulan link penomoran halaman, dengan gaya link secara visual untuk mewakili halaman yang saat ini ditampilkan. [Aplikasi Rich Internet yang Dapat Diakses (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)

Dengan atribut tambahan, pembaca layar kini membacakan sesuatu seperti "halaman saat ini, link, Tentang Kami" alih-alih hanya "tautan, Tentang Kami".

<a href="/about-us" aria-current="page" class="active-page">About us</a>

Efek samping yang praktis adalah Anda dapat menggunakan atribut untuk memilih link aktif di CSS, sehingga class active-page menjadi tidak berlaku lagi.

<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
  --border-color: var(--color-highlight);
  --text-color: var(--color-highlight);
}
Lihat Langkah 2: Tandai halaman yang aktif di CodePen.

Mengumumkan jumlah item

Dengan melihat navigasinya, pengguna yang mampu melihat dapat mengetahui bahwa navigasi itu hanya berisi empat tautan. Pengguna pembaca layar tunanetra tidak dapat memperoleh informasi ini dengan cepat. Mereka mungkin harus memeriksa seluruh daftar link. Hal ini mungkin tidak menjadi masalah jika daftarnya pendek seperti dalam contoh ini, tetapi jika berisi 40 link, tugas ini bisa menjadi rumit. Jika pengguna pembaca layar tahu dari awal bahwa navigasinya berisi banyak tautan, mereka mungkin memutuskan untuk menggunakan cara navigasi yang berbeda dan lebih efisien, seperti penelusuran situs.
Cara yang bagus untuk mengomunikasikan jumlah item di awal, adalah mengemas setiap link dalam item daftar (<li>), yang disarangkan dalam daftar yang tidak diurutkan (<ul>).

<ul>
  <li>
     <a href="/home">Home</a>
  </li>
  <li>
    <a href="/about-us" aria-current="page">About us</a>
  </li>
  <li>
    <a href="/pricing">Pricing</a>
  </li>
  <li>
    <a href="/contact">Contact</a>
  </li>
</ul>

Saat pengguna pembaca layar menemukan daftar tersebut, software mereka akan mengucapkan sesuatu seperti "cantumkan, 4 item".

Berikut adalah demo navigasi yang digunakan dengan NVDA pembaca layar di Windows.

Sekarang Anda harus menyesuaikan gaya agar terlihat seperti sebelumnya.

/* Remove the default list styling and create a flexible layout for the list */
ul {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Basic link styling */
a {
  --text-color: var(--color-shades-dark);

  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  padding: 0.1rem;
  text-decoration: none;
}

Menggunakan daftar dapat memberikan banyak keuntungan bagi pengguna pembaca layar:

  • Mereka bisa mendapatkan jumlah total item sebelum mereka berinteraksi dengan item tersebut.
  • Mereka dapat menggunakan pintasan untuk beralih dari item daftar ke item daftar.
  • Mereka mungkin menggunakan pintasan untuk beralih dari satu daftar ke daftar yang lain.
  • Pembaca layar dapat mengucapkan indeks item saat ini (misalnya, "item daftar, dua dari empat").

Selain itu, jika halaman disajikan tanpa CSS, daftar tersebut akan menampilkan link sebagai kelompok item yang koheren, bukan hanya tumpukan link.

Detail penting tentang VoiceOver di Safari adalah Anda kehilangan semua keuntungan ini, jika menetapkan list-style: none. Hal ini sesuai dengan desain. Tim WebKit memutuskan untuk menghapus semantik daftar, jika daftar tidak tampak seperti daftar. Bergantung pada kerumitan navigasi Anda, hal ini mungkin menjadi masalah atau tidak. Di satu sisi, navigasi masih dapat digunakan dan hanya memengaruhi VoiceOver di Safari. VoiceOver dengan Chrome atau Firefox masih mengumumkan jumlah item, serta pembaca layar lainnya, seperti NVDA. Di sisi lain, informasi semantik sangat berguna dalam beberapa situasi. Untuk membuat keputusan itu, Anda harus menguji navigasi dengan pengguna pembaca layar yang sebenarnya dan mendapatkan umpan balik mereka. Jika Anda memutuskan bahwa VoiceOver di Safari harus berperilaku seperti pembaca layar lainnya, Anda dapat mengatasi masalah ini dengan menetapkan peran daftar ARIA secara eksplisit di <ul>. Tindakan ini akan mengembalikan perilaku ke status sebelum Anda menghapus gaya visual daftar. Secara visual, daftar tersebut masih terlihat sama.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Lihat Langkah 3: Mengumumkan jumlah item di CodePen.

Menambahkan tempat terkenal

Dengan sedikit upaya, Anda telah melakukan peningkatan besar bagi pengguna pembaca layar, tetapi ada satu hal lagi yang dapat Anda lakukan. Navigasi secara semantik masih merupakan daftar tautan dan sulit untuk mengetahui bahwa daftar spesifik ini adalah navigasi utama situs Anda. Anda dapat mengubah daftar biasa ini menjadi daftar navigasi dengan menggabungkan <ul> dalam elemen <nav>.

Menggunakan elemen <nav> memiliki beberapa keuntungan. Secara khusus, pembaca layar membacakan sesuatu seperti "navigasi", saat pengguna berinteraksi dengannya, dan menambahkan landmark ke halaman. Penanda adalah wilayah khusus pada halaman, seperti <header>, <footer>, atau <main>, tempat pembaca layar dapat melompat. Memiliki {i>landmark<i} di halaman dapat bermanfaat, karena memungkinkan pengguna pembaca layar untuk mengakses area penting pada halaman secara langsung tanpa harus berinteraksi dengan bagian halaman lainnya. Misalnya, Anda dapat melompat dari tempat terkenal ke tempat terkenal dengan menekan tombol D di NVDA. Di Voice Over, Anda dapat menggunakan rotor untuk mencantumkan semua tempat terkenal di halaman dengan menekan VO + U.

Daftar empat {i>landmark<i}: banner, navigasi, utama, informasi konten.
Rotor di VoiceOver mencantumkan semua tempat terkenal di halaman.

Dalam daftar ini, Anda akan melihat 4 penanda: banner yang merupakan elemen <header>, navigasi adalah <nav>, utama elemen <main>, dan informasi konten adalah <footer>. Daftar ini tidak boleh terlalu panjang, Anda sebenarnya hanya ingin menandai bagian penting UI Anda sebagai penanda, seperti penelusuran situs, navigasi lokal, atau penomoran halaman.

Jika memiliki navigasi seluruh situs, navigasi lokal untuk halaman, dan penomoran halaman di satu halaman, Anda mungkin juga memiliki 3 elemen <nav>. Tidak masalah, tetapi sekarang ada tiga penanda navigasi dan secara semantik semuanya terlihat sama. Sulit untuk membedakannya, kecuali jika Anda mengetahui struktur halamannya dengan sangat baik.

Gambar yang menampilkan tiga tempat terkenal yang semuanya bertuliskan &#39;navigation&#39;.
Rotor di VoiceOver mencantumkan tiga penanda navigasi tidak berlabel.

Agar dapat dibedakan, Anda harus melabelinya dengan menggunakan aria-labelledby atau aria-label.

<nav aria-label="Main">
    <ul>
      <li>
         <a href="/home">Home</a>
      </li>
      ...
  </ul>
</nav>
...
<nav aria-label="Select page">
    <ul>
      <li>
         <a href="/page-1">1</a>
      </li>
      ...
    </ul>
</nav>

Jika label yang Anda pilih sudah ada di suatu tempat di halaman, sebagai gantinya Anda dapat menggunakan aria-labelledby dan mereferensikan label yang ada menggunakan atribut id.

<nav aria-labelledby="pagination_heading">
  <h2 id="pagination_heading">Select a page</h2>
  <ul>
    <li>
       <a href="/page-1">1</a>
    </li>
    ...
  </ul>
</nav>

Label yang ringkas sudah cukup, jangan terlalu bertele-tele. Menghilangkan ekspresi seperti "navigasi" atau "menu" karena pembaca layar sudah menyediakan informasi ini kepada pengguna.

Tempat terkenal
VoiceOver mencantumkan penanda "banner", "navigasi utama", "utama", "navigasi halaman", "pilih navigasi halaman" dan "informasi konten".
Lihat Langkah 4: Menambahkan tempat terkenal di CodePen.

Menyembunyikan navigasi di area pandang yang sempit

Secara pribadi, saya tidak suka menyembunyikan navigasi utama di area pandang yang sempit, tetapi jika daftar link terlalu panjang, tidak ada jalan lain. Jika demikian, pengguna akan melihat tombol berlabel "Menu" alih-alih daftarnya atau ikon burger atau kombinasi di antaranya. Mengklik tombol akan menampilkan dan menyembunyikan daftar. Jika Anda mengetahui JavaScript dan CSS dasar, itu adalah tugas yang dapat dilakukan, tetapi ada beberapa hal dalam hal UX dan aksesibilitas yang harus Anda perhatikan.

  • Anda harus menyembunyikan daftar dengan cara yang mudah diakses.
  • Navigasi harus dapat diakses dari keyboard.
  • Navigasi harus menunjukkan apakah navigasi terlihat atau tidak.

Menambahkan tombol burger

Karena Anda mengikuti prinsip progressive enhancement, Anda ingin memastikan bahwa navigasi Anda tetap berfungsi dan masuk akal meskipun JavaScript dinonaktifkan.
Hal pertama yang dibutuhkan navigasi Anda adalah tombol burger. Anda membuatnya di HTML dalam elemen template, membuat clone di JavaScript, dan menambahkannya ke navigasi.

Halaman yang menampilkan tombol burger.
Hasil: Navigasi menampilkan tombol burger di area pandang yang sempit, bukan link.
<nav id="mainnav">
  ...
</nav>

<template id="burger-template">
  <button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
    <svg width="24" height="24" aria-hidden="true">
      <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
    </svg>
  </button>
</template>
  1. Atribut aria-expanded memberi tahu software pembaca layar apakah elemen yang dikontrol tombol diperluas atau tidak.
  2. aria-label memberi tombol ini nama yang dapat diakses, yaitu alternatif teks untuk ikon burger.
  3. Anda menyembunyikan <svg> dari teknologi pendukung menggunakan aria-hidden karena sudah memiliki label teks yang disediakan oleh aria-label.
  4. aria-controls memberi tahu teknologi pendukung, yang mendukung atribut (misalnya JAWS), yang merupakan elemen yang dikontrol tombol.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');

// Toggle aria-expanded attribute
button.addEventListener('click', e => {
  // aria-expanded="true" signals that the menu is currently open
  const isOpen = button.getAttribute('aria-expanded') === "true"
  button.setAttribute('aria-expanded', !isOpen);
});

// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    button.setAttribute('aria-expanded', false);
  }
});

// Add the button to the page
nav.insertBefore(burgerClone, list);
  1. Pengguna dapat menutup navigasi kapan pun mereka mau, misalnya dengan menekan tombol Escape.
  2. Penting untuk menggunakan insertBefore, bukan appendChild, karena tombol harus menjadi elemen pertama dalam navigasi Anda. Jika pengguna keyboard atau pembaca layar menekan Tab setelah mengklik tombol, mereka ingin memfokuskan item pertama dalam daftar. Jika tombol muncul setelah daftar, hal itu tidak akan terjadi.

Selanjutnya, Anda mereset gaya default tombol dan memastikan tombol hanya terlihat di area pandang yang sempit.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
  }
}

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
Lihat Langkah 5: Menambahkan tombol burger di CodePen.

Menyembunyikan daftar

Sebelum menyembunyikan daftar, posisikan dan tata gaya navigasi dan daftar sehingga tata letak dioptimalkan untuk area pandang yang sempit, tetapi tetap terlihat bagus di layar yang lebih besar.
Pertama, hapus <nav> dari alur alami halaman dan tempatkan di sudut ujung atas area pandang.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
}

nav {
  position: var(--nav-position, fixed);
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
}

Selanjutnya, ubah tata letak pada area pandang sempit dengan menambahkan properti khusus baru (—-nav-list-layout). Tata letak adalah kolom secara default dan beralih ke baris pada layar yang lebih besar.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }

  ul {
    --nav-list-layout: row;
  }
}

ul {
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

Navigasi Anda akan terlihat seperti ini di area pandang yang sempit.

Halaman yang menampilkan daftar navigasi dan tombol burger.
Tombol burger dan daftarnya ditempatkan di sudut ujung atas area tampilan.

Daftar ini jelas membutuhkan beberapa CSS. Kita akan memindahkannya ke sudut akhir atas, membuatnya mengisi seluruh layar secara vertikal, menerapkan background-color dan box-shadow.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
  
  ul {
    --nav-list-layout: row;
    --nav-list-position: static;
    --nav-list-padding: 0;
    --nav-list-height: auto;
    --nav-list-width: 100%;
    --nav-list-shadow: none;
  }
}

ul {
  background: rgb(255, 255, 255);
  box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  height: var(--nav-list-height, 100vh);
  list-style: none;
  margin: 0;
  padding: var(--nav-list-padding, 2rem);
  position: var(--nav-list-position, fixed);
  inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
  inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
  width: var(--nav-list-width, min(22rem, 100vw));
}

button {
  all: unset;
  display: var(--nav-button-display, flex);
  position: relative;
  z-index: 1;
}

Daftar tersebut akan terlihat seperti ini di area pandang yang sempit, lebih seperti sidebar daripada daftar sederhana.

Daftar navigasi akan terbuka.

Terakhir, sembunyikan daftar, hanya tampilkan saat pengguna mengklik tombol sekali dan sembunyikan saat mereka mengklik lagi. Penting untuk hanya menyembunyikan daftar, bukan seluruh navigasi, karena menyembunyikan navigasi juga akan berarti menyembunyikan penanda yang penting.

Sebelumnya, Anda menambahkan peristiwa klik ke tombol untuk mengalihkan nilai atribut aria-expanded. Anda dapat menggunakan informasi tersebut sebagai kondisi untuk menampilkan dan menyembunyikan daftar di CSS.

@media (min-width: 48em) {
  ul {
    --nav-list-visibility: visible;
  }
}

ul {
  visibility: var(--nav-list-visibility, visible);
}

/* Hide the list on narrow viewports, if it comes after an element with
   aria-expanded set to "false". */
[aria-expanded="false"] + ul {
  visibility: var(--nav-list-visibility, hidden);
}

Anda harus menggunakan deklarasi properti seperti visibility: hidden atau display: none, bukan opacity: 0 atau translateX(100%), untuk menyembunyikan daftar. Properti ini memastikan bahwa link tidak dapat difokuskan saat navigasi disembunyikan. Menggunakan opacity atau translate akan menghapus konten secara visual sehingga link tidak akan terlihat namun masih dapat diakses menggunakan keyboard yang akan membingungkan dan merepotkan. Menggunakan visibility atau display akan menyembunyikannya secara visual dan membuatnya tidak dapat diakses, sehingga menyembunyikannya untuk semua pengguna.

Lihat Langkah 6: Menyembunyikan daftar.

Menganimasikan daftar

Jika Anda ingin tahu alasan menggunakan visibility: hidden; dibandingkan display: none;, ini karena Anda dapat menganimasikan visibilitas. Class ini hanya memiliki dua status, hidden dan visible, tetapi Anda dapat menggabungkannya dengan properti lain seperti transform atau opacity untuk membuat efek geser atau fade-in. Itu tidak akan berfungsi dengan display: tidak ada karena properti tampilan tidak dapat dianimasikan.

Transisi CSS berikut opacity untuk membuat efek fade-in dan fade-out.

ul {
  transition: opacity 0.6s linear, visibility 0.3s linear;
  visibility: var(--nav-list-visibility, visible);
}

[aria-expanded="false"] + ul {
  opacity: 0;
  visibility: var(--nav-list-visibility, hidden);
}

Jika ingin menganimasikan gerakan, Anda harus mempertimbangkan untuk menggabungkan properti transition dalam kueri media preferensi-reduced-motion karena animasi dapat memicu mual, pusing, dan sakit kepala pada beberapa pengguna.

ul {
  visibility: var(--nav-list-visibility, visible);
}

@media (prefers-reduced-motion: no-preference) {
  ul {
    transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
  }
}

[aria-expanded="false"] + ul {
  transform: var(--nav-list-transform, translateX(100%));
  visibility: var(--nav-list-visibility, hidden);
}

Cara ini memastikan bahwa hanya orang yang tidak memiliki preferensi terhadap gerakan yang dikurangi yang akan melihat animasinya.

Lihat Langkah 7: Membuat animasi daftar di CodePen.

Meningkatkan gaya visual fokus

Pengguna keyboard bergantung pada gaya fokus elemen untuk orientasi dan navigasi pada halaman. Gaya fokus default lebih baik daripada tidak ada gaya fokus (yang terjadi jika Anda menetapkan outline: none), tetapi memiliki gaya fokus kustom yang lebih jelas akan meningkatkan pengalaman pengguna.

Berikut adalah tampilan gaya fokus default pada link di Chrome 103.

Garis batas 2 piksel biru di sekitar link yang difokuskan di Chrome 103.

Anda dapat meningkatkannya dengan menyediakan gaya Anda sendiri dalam warna Anda sendiri. Dengan menggunakan :focus-visible, bukan :focus, Anda memungkinkan browser memutuskan kapan waktu yang tepat untuk menampilkan gaya fokus. Gaya :focus akan dapat dilihat oleh semua pengguna, mouse, keyboard, dan pengguna sentuh, terlepas dari apakah mereka membutuhkannya atau tidak. Dengan :focus-visible, browser menggunakan heuristik internal untuk memutuskan apakah akan menampilkannya hanya kepada pengguna keyboard atau semua orang.

/* Remove the default :focus outline */
*:focus {
  outline: none;
}

/* Show a custom outline on :focus-visible */
*:focus-visible {
  outline: 2px solid var(--color-shades-dark);
  outline-offset: 4px;
}

Dukungan browser untuk :focus-visible

Dukungan Browser

  • Chrome: 86.
  • Edge: 86.
  • Firefox: 85.
  • Safari: 15.4.

Sumber

Garis batas 2 px gelap yang terlihat jelas dengan spasi di dalamnya.

Ada berbagai cara untuk menyoroti item saat item tersebut difokuskan. Sebaiknya gunakan properti outline karena tidak merusak tata letak, yang dapat terjadi dengan border, dan berfungsi dengan baik dengan mode kontras tinggi di Windows. Properti yang tidak berfungsi dengan baik adalah background-color atau box-shadow, karena mungkin tidak ditampilkan sama sekali dengan setelan kontras kustom.

Situs dengan latar belakang gelap dengan fokus yang disorot dengan warna ungu.
Lihat Langkah 8: Tingkatkan gaya fokus di CodePen.

Selamat! Anda telah membuat navigasi utama yang disempurnakan secara bertahap, beragam semantik, mudah diakses, dan mobile-friendly.

Selalu ada hal yang dapat ditingkatkan, misalnya:

  • Anda dapat mempertimbangkan untuk menjepit fokus di dalam navigasi atau membuat bagian lain halaman menjadi inert di area pandang yang sempit.
  • Anda dapat menambahkan link lewati di bagian atas halaman untuk memungkinkan pengguna keyboard melewati navigasi.

Jika Anda ingat bagaimana artikel ini dimulai, dengan tujuan bahwa solusinya "tidak terlalu sederhana, atau terlalu rumit", di situlah kita sekarang. Namun, ada kemungkinan untuk merekayasa navigasi secara berlebihan.

Ada perbedaan yang jelas antara navigasi dan menu. Navigasi adalah kumpulan tautan untuk menavigasi dokumen terkait. Menu adalah kumpulan tindakan yang akan dilakukan dalam dokumen. Terkadang tugas-tugas ini tumpang tindih. Anda mungkin memiliki navigasi yang juga menyertakan tombol yang melakukan tindakan, seperti membuka jendela modal, atau Anda mungkin memiliki menu di mana satu tindakan menavigasi ke halaman lain, seperti halaman bantuan. Jika demikian, jangan menggabungkan peran ARIA, tetapi sebaiknya identifikasi tujuan utama komponen Anda dan pilih markup serta peran yang sesuai.

Elemen <nav> memiliki peran navigasi ARIA implisit yang memadai untuk menyampaikan bahwa elemen tersebut adalah navigasi, tetapi sering kali Anda melihat situs juga menggunakan menu, panel menu, dan item menu. Karena kami terkadang menggunakan istilah-istilah ini secara bergantian, menggabungkan istilah-istilah ini untuk meningkatkan pengalaman bagi pengguna pembaca layar mungkin masuk akal. Sebelum mempelajari mengapa hal itu biasanya tidak terjadi, mari kita lihat definisi resmi dari peran-peran ini.

Peran navigasi

Kumpulan elemen navigasi (biasanya link) untuk menavigasi dokumen atau dokumen terkait.

navigation (peran) WAI-ARIA 1.1

Peran menu

Menu sering kali merupakan daftar tindakan atau fungsi umum yang dapat dipanggil pengguna. Peran menu sesuai saat daftar item menu ditampilkan dengan cara yang mirip dengan menu di aplikasi desktop.

menu (peran) WAI-ARIA 1.1

Peran panel menu

Presentasi menu yang biasanya tetap terlihat dan biasanya disajikan secara horizontal. Peran bilah menu digunakan untuk membuat bilah menu yang mirip dengan yang ditemukan di aplikasi desktop Windows, Mac, dan Gnome. Panel menu digunakan untuk membuat serangkaian perintah yang sering digunakan secara konsisten. Penulis harus memastikan bahwa interaksi menubar serupa dengan interaksi panel menu biasa pada antarmuka pengguna grafis desktop.

menubar (peran) WAI-ARIA 1.1

Peran item menu

Opsi dalam kumpulan pilihan yang terdapat oleh menu atau menubar.

menuitem (peran) WAI-ARIA 1.1

Spesifikasinya sangat jelas di sini, gunakan navigasi untuk menavigasi dokumen atau dokumen dan menu terkait hanya untuk daftar tindakan atau fungsi yang mirip dengan menu di aplikasi desktop. Jika Anda tidak membuat Google Dokumen berikutnya, Anda mungkin tidak memerlukan peran menu apa pun untuk navigasi utama.

Kapan menu yang tepat?

Penggunaan utama item menu bukanlah navigasi, tetapi untuk melakukan tindakan. Misalkan Anda memiliki daftar atau tabel data dan pengguna dapat melakukan tindakan tertentu pada setiap item dalam daftar. Anda dapat menambahkan tombol ke setiap baris dan menampilkan tindakan saat pengguna mengklik tombol tersebut.

<ul>
  <li>
    Product 1

    <button aria-expanded="false" aria-controls="options1">Edit</button>

    <div role="menu" id="options1">
      <button role="menuitem">
        Duplicate
      </button>
      <button role="menuitem">
        Delete
      </button>
      <button role="menuitem">
        Disable
      </button>
    </div>
  </li>
  <li>
    Product 2
    ...
  </li>
</ul>

Implikasi penggunaan peran menu

Gunakan peran menu ini dengan bijak, karena banyak hal yang bisa salah.

Menu mengharapkan struktur DOM tertentu. menuitem harus berupa item turunan langsung dari menu. Kode berikut dapat merusak perilaku semantik:

 <!-- Wrong, don't do this -->
<ul role="menu">
  <li>
    <a href="#" role="menuitem">Item 1</a>
  </li>
</ul>

Pengguna yang cerdas berharap agar pintasan {i>keyboard<i} tertentu berfungsi dengan menu dan bilah menu. Berdasarkan ARIA Authoring Practices Guide (APG), hal ini mencakup:

  • Enter dan Spasi untuk memilih item menu.
  • Tombol panah ke semua arah untuk beralih antar-item.
  • Tombol Beranda dan Akhir untuk memindahkan fokus ke item pertama atau terakhir.
  • a-z untuk memindahkan fokus ke item menu berikutnya dengan label yang dimulai dengan karakter yang diketik.
  • Tekan Esc untuk menutup menu.

Jika pembaca layar mendeteksi sebuah menu, software mungkin secara otomatis mengubah mode penjelajahan, sehingga memungkinkan penggunaan pintasan yang disebutkan sebelumnya. Pengguna pembaca layar yang tidak berpengalaman mungkin tidak dapat menggunakan menu karena tidak mengetahui pintasan tersebut atau cara menggunakannya.

Hal ini sama untuk pengguna keyboard yang mungkin berharap bahwa mereka dapat menggunakan Shift dan Shift + Tab.

Ada banyak hal yang perlu dipertimbangkan saat Anda membuat menu dan bilah menu, apakah sesuai untuk menggunakannya sejak awal. Ketika Anda membangun {i>website<i} pada umumnya, yang Anda butuhkan hanyalah elemen navigasi dengan daftar dan tautan. Kebijakan ini juga mencakup Aplikasi Web Satu Halaman (SPA) atau aplikasi web. Stack yang mendasarinya tidak menjadi masalah. Kecuali Anda membangun sesuatu yang sangat dekat dengan aplikasi {i>desktop<i}, hindari peran menu.

Referensi Tambahan

Banner besar oleh Mick Haupt