Web Development

HTML Semantics & Accessibility: Panduan Lengkap

Pelajari HTML semantik dan accessibility secara mendalam β€” elemen semantik HTML5, ARIA attributes, screen reader compatibility, WCAG guidelines, dan praktik terbaik untuk membangun web yang inklusif untuk semua pengguna

1. Pengenalan Semantics & Accessibility

HTML Semantics dan Accessibility (a11y) adalah dua konsep fundamental yang saling berkaitan dalam pengembangan web modern. HTML semantik menggunakan elemen-elemen yang memiliki makna jelas, bukan hanya sekadar pembungkus visual. Accessibility memastikan bahwa semua orang β€” termasuk penyandang disabilitas β€” dapat menggunakan website dengan baik.

Menurut World Health Organization (WHO), lebih dari 1 miliar orang di dunia memiliki disabilitas tertentu. Membuat website yang aksesibel bukan hanya etika yang baik, tetapi juga merupakan kewajiban hukum di banyak negara dan dapat meningkatkan SEO serta pengalaman pengguna secara keseluruhan.

Mengapa Semantics Penting?

Aspek Dampak Semantics
AccessibilityScreen reader dapat memahami struktur dan konten halaman dengan benar
SEOMesin pencari lebih mudah mengindeks konten berdasarkan makna elemen
MaintainabilityKode lebih mudah dibaca dan dipahami oleh developer lain
KonsistensiSemua developer menggunakan elemen yang sama untuk tujuan yang sama
Future-ProofBrowser baru akan terus mendukung elemen semantik dengan lebih baik
InteroperabilitasAlat bantu, pembaca layar, dan bot dapat memahami konten secara tepat

Non-Semantic vs Semantic HTML

Diagram: Perbandingan Non-Semantic vs Semantic
  ❌ NON-SEMANTIK                    βœ… SEMANTIK
  ─────────────────                  ─────────────────
  <div id="header">                  <header>
    <div id="nav">                     <nav>
      <div class="link">                <a href="/">Home</a>
        <a href="/">Home</a>             <a href="/about">Tentang</a>
      </div>                           </nav>
    </div>                           </header>
  </div>

  <div id="content">                 <main>
    <div class="article">              <article>
      <div class="title">               <h1>Judul Artikel</h1>
        <h1>Judul</h1>                   <p>Isi artikel...</p>
      </div>                           </article>
    </div>                           </main>
  </div>

  <div id="footer">                  <footer>
    <p>Β© 2026</p>                     <p>Β© 2026</p>
  </div>                            </footer>
πŸ’‘ Tips

Jangan gunakan <div> dan <span> untuk semuanya. Gunakan elemen semantik yang tepat seperti <header>, <nav>, <main>, <article>, <section>, <aside>, dan <footer>.

2. Elemen Semantik HTML5

HTML5 memperkenalkan banyak elemen semantik yang memberikan makna pada konten. Elemen-elemen ini membantu browser, mesin pencari, dan teknologi assistif untuk memahami struktur halaman web.

Elemen Struktur Dokumen

Elemen Fungsi Contoh Penggunaan
<header>Pembuka bagian atau halamanLogo, navigasi, judul halaman
<nav>Navigasi utamaMenu utama, breadcrumb, sidebar links
<main>Konten utama halamanIsi artikel yang unik di halaman
<article>Konten yang mandiriBlog post, berita, komentar, card
<section>Pengelompokan tematikBab, chapter, topik tertentu
<aside>Konten pelengkapSidebar, widget, referensi terkait
<footer>Penutup bagian atau halamanCopyright, link kontak, social media

Elemen Konten Teks

Elemen Fungsi Contoh
<h1>–<h6>Judul hierarkiJudul utama hingga sub-sub-judul
<p>ParagrafBlok teks
<blockquote>Kutipan blokKutipan dari sumber eksternal
<cite>Judul karyaNama buku, film, lagu
<figure>Konten terpasangGambar dengan caption
<figcaption>Caption figureKeterangan gambar
<time>Tanggal/waktu<time datetime="2026-06-26">26 Juni 2026</time>
<mark>Teks disorotKata kunci yang relevan
<abbr>Singkatan<abbr title="Hypertext Markup Language">HTML</abbr>
<code>Kode komputerInline code snippet
<pre>Teks preformattedBlok kode
<strong>Penekanan kuatTeks penting (bold + semantic)
<em>PenekananTeks yang ditekankan (italic + semantic)

Contoh Struktur Semantik Lengkap

<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <title>Website Semantik</title>
</head>
<body>
  <header>
    <h1>Nama Website</h1>
    <nav aria-label="Navigasi utama">
      <ul>
        <li><a href="/">Beranda</a></li>
        <li><a href="/artikel">Artikel</a></li>
        <li><a href="/kontak">Kontak</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <article>
      <header>
        <h2>Judul Artikel</h2>
        <time datetime="2026-06-26">26 Juni 2026</time>
        <p>Oleh <a rel="author">Penulis</a></p>
      </header>

      <section>
        <h3>Bab 1: Pendahuluan</h3>
        <p>Isi artikel...</p>
      </section>

      <section>
        <h3>Bab 2: Pembahasan</h3>
        <p>Isi pembahasan...</p>
        <figure>
          <img src="diagram.png" alt="Diagram alur proses">
          <figcaption>Gambar 1: Diagram alur kerja aplikasi</figcaption>
        </figure>
      </section>

      <aside aria-label="Artikel terkait">
        <h3>Artikel Terkait</h3>
        <ul>
          <li><a href="/artikel-1">Artikel Satu</a></li>
        </ul>
      </aside>
    </article>
  </main>

  <footer>
    <p>&copy; 2026 Nama Website</p>
    <nav aria-label="Footer links">
      <ul>
        <li><a href="/privacy">Privasi</a></li>
      </ul>
    </nav>
  </footer>
</body>
</html>

3. Struktur Dokumen Semantik

Memahami bagaimana elemen-elemen semantik saling berkaitan dalam struktur dokumen sangat penting. Heading hierarchy (<h1> hingga <h6>) harus mengikuti pola yang logis dan tidak loncat level.

Heading Hierarchy yang Benar

<!-- βœ… BENAR: Hierarki berurutan -->
<h1>Judul Utama Website</h1>
  <h2>Judul Bagian</h2>
    <h3>Sub-Bagian</h3>
    <h3>Sub-Bagian Lain</h3>
      <h4>Sub-Sub-Bagian</h4>
  <h2>Bagian Kedua</h2>

<!-- ❌ SALAH: Melompat level -->
<h1>Judul Utama</h1>
  <h4>Lompat ke h4</h4>    <!-- Jangan lompat! -->
  <h2>Baru h2</h2>

Elemen <section> vs <div>

Gunakan <section> ketika konten memiliki heading sendiri dan merupakan topik yang berbeda. Gunakan <div> hanya untuk grouping tanpa makna semantik (misalnya untuk styling).

<!-- βœ… Section: konten tematik dengan heading -->
<section>
  <h2>Fitur Produk</h2>
  <p>Deskripsi fitur...</p>
</section>

<!-- βœ… Div: hanya untuk styling -->
<div class="card-grid">
  <div class="card">...</div>
  <div class="card">...</div>
</div>

Elemen <article> yang Mandiri

<article> harus bisa dipahami secara mandiri. Konten di dalam <article> harus tetap bermakna meskipun dipindahkan ke halaman lain.

<!-- Contoh: Comment sebagai article terpisah -->
<article class="comment">
  <header>
    <h4>Komentar oleh Budi</h4>
    <time datetime="2026-06-26T10:30">26 Juni 2026, 10:30</time>
  </header>
  <p>Artikel yang sangat informatif!</p>
  <footer>
    <a href="#reply">Balas</a>
  </footer>
</article>

Elemen Konten Tersembunyi

Elemen/Metode Fungsi Screen Reader
display: noneSembunyikan dari semuaTidak dibaca
visibility: hiddenSembunyikan, pertahankan ruangTidak dibaca
aria-hidden="true"Sembunyikan dari AT sajaTidak dibaca
.sr-only / .visually-hiddenSembunyikan visual, baca oleh ATDibaca βœ…
hidden attributeSembunyikan dari semuaTidak dibaca
/* CSS untuk elemen yang hanya terlihat oleh screen reader */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

4. ARIA Roles & Attributes

ARIA (Accessible Rich Internet Applications) adalah spesifikasi dari W3C yang menyediakan atribut tambahan untuk meningkatkan aksesibilitas elemen HTML. ARIA memperluas HTML agar aplikasi web kompleks dapat dipahami oleh teknologi assistif.

⚠️ Aturan Pertama ARIA

"Jangan gunakan ARIA jika bisa menggunakan elemen HTML semantik." Misalnya, gunakan <button> daripada <div role="button">. Elemen semantik sudah memiliki role dan perilaku bawaan.

ARIA Roles

Role Fungsi Contoh
role="navigation"Menandai area navigasiBisa digunakan jika tidak pakai <nav>
role="banner"Header utama halamanAlternatif <header>
role="main"Konten utamaAlternatif <main>
role="alert"Pesan pentingNotifikasi error/sukses
role="dialog"Dialog/modalPopup konfirmasi
role="tablist"Daftar tabTab component
role="tab"Tab individuTombol tab
role="tabpanel"Panel konten tabIsi dari tab
role="progressbar"Progress barLoading indicator
role="status"Status update liveJumlah item di keranjang

ARIA Properties & States

Atribut Fungsi Contoh
aria-labelLabel aksesibel<button aria-label="Tutup">βœ•</button>
aria-labelledbyReferensi ke elemen labelaria-labelledby="title1"
aria-describedbyDeskripsi tambahanaria-describedby="hint1"
aria-hiddenSembunyikan dari ATaria-hidden="true" pada ikon dekoratif
aria-expandedStatus buka/tutupAccordion, dropdown
aria-selectedStatus terpilihTab yang aktif
aria-checkedStatus centangCheckbox custom
aria-disabledNonaktifkan untuk ATTombol disabled
aria-liveKonten berubah dinamisaria-live="polite" untuk update
aria-requiredField wajibForm input required
aria-invalidField tidak validForm validation error

Contoh Implementasi ARIA

<!-- Custom Button dengan ARIA -->
<div role="button"
     tabindex="0"
     aria-label="Tambahkan ke keranjang"
     onclick="addToCart()"
     onkeydown="if(event.key==='Enter') addToCart()">
  πŸ›’ Tambah ke Keranjang
</div>

<!-- Accordion dengan ARIA -->
<div class="accordion">
  <button aria-expanded="false"
          aria-controls="panel-1"
          id="btn-1">
    Klik untuk membuka
  </button>
  <div id="panel-1"
       role="region"
       aria-labelledby="btn-1"
       hidden>
    <p>Konten accordion yang tersembunyi.</p>
  </div>
</div>

<!-- Modal Dialog -->
<div role="dialog"
     aria-modal="true"
     aria-labelledby="dialog-title"
     aria-describedby="dialog-desc">
  <h2 id="dialog-title">Konfirmasi Hapus</h2>
  <p id="dialog-desc">Apakah Anda yakin ingin menghapus item ini?</p>
  <button>Ya, Hapus</button>
  <button>Batal</button>
</div>

<!-- Live Region untuk notifikasi -->
<div aria-live="polite" aria-atomic="true" class="sr-only">
  <!-- Pesan akan diumumkan oleh screen reader -->
  Item berhasil ditambahkan ke keranjang
</div>

ARIA Live Regions

<!-- Polite: Diumumkan saat idle -->
<div aria-live="polite">
  3 hasil pencarian ditemukan
</div>

<!-- Assertive: Diumumkan segera (ganggu) -->
<div aria-live="assertive">
  ⚠️ Koneksi terputus!
</div>

<!-- Status: Kombinasi role="status" + aria-live="polite" -->
<div role="status">
  Form berhasil disimpan
</div>

<!-- Timer: Countdown -->
<div role="timer" aria-live="off" aria-label="Waktu tersisa">
  05:30
</div>

5. Screen Reader & Assistive Technology

Screen reader adalah software yang membaca konten halaman web secara verbal kepada pengguna tunanetra atau yang memiliki kesulitan penglihatan. Memahami cara kerja screen reader sangat penting untuk membuat web yang aksesibel.

Screen Reader Populer

Screen Reader Platform Harga Pengguna
NVDAWindowsGratis (Open Source)Sangat populer
JAWSWindowsBerbayar ($1000)Populer di enterprise
VoiceOvermacOS / iOSBawaan sistemPopuler di Apple ecosystem
TalkBackAndroidBawaan sistemPopuler di Android
NarratorWindowsBawaan sistemBasic accessibility
OrcaLinuxGratisScreen reader Linux

Cara Screen Reader Membaca Halaman

Diagram: Alur Pembacaan Screen Reader
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚         SCREEN READER FLOW           β”‚
  β”‚                                      β”‚
  β”‚  1. Baca <title> halaman            β”‚
  β”‚  2. Baca landmark regions:           β”‚
  β”‚     β”œβ”€β”€ <header> / role="banner"     β”‚
  β”‚     β”œβ”€β”€ <nav> / role="navigation"    β”‚
  β”‚     β”œβ”€β”€ <main> / role="main"         β”‚
  β”‚     β”œβ”€β”€ <aside> / role="complementaryβ”‚
  β”‚     └── <footer> / role="contentinfo"β”‚
  β”‚  3. Baca heading hierarchy           β”‚
  β”‚     └── h1 β†’ h2 β†’ h3 β†’ ...          β”‚
  β”‚  4. Baca konten linear               β”‚
  β”‚     β”œβ”€β”€ Links: "Link, [teks]"        β”‚
  β”‚     β”œβ”€β”€ Buttons: "Button, [label]"   β”‚
  β”‚     β”œβ”€β”€ Images: [alt text]           β”‚
  β”‚     β”œβ”€β”€ Forms: "[label], edit"       β”‚
  β”‚     └── Tables: navigasi sel         β”‚
  β”‚  5. Umumkan live region changes      β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Best Practices untuk Screen Reader

<!-- 1. Selalu berikan alt text pada gambar -->
<img src="chart.png"
     alt="Grafik penjualan naik 25% dari Q1 ke Q2 2026">

<!-- 2. Gunakan alt="" untuk gambar dekoratif -->
<img src="divider.png" alt="" role="presentation">

<!-- 3. Berikan label pada form inputs -->
<label for="email">Alamat Email</label>
<input type="email" id="email" name="email">

<!-- 4. Gunakan lang attribute -->
<html lang="id">
<p>Ini bahasa Indonesia, <span lang="en">this is English</span></p>

<!-- 5. Tambahkan skip navigation link -->
<a href="#main-content" class="skip-link">Skip ke konten utama</a>

<!-- 6. Berikan konteks pada tabel -->
<table>
  <caption>Daftar harga paket hosting</caption>
  <thead>
    <tr><th scope="col">Paket</th><th scope="col">Harga</th></tr>
  </thead>
  <tbody>
    <tr><td>Basic</td><td>Rp 50.000/bulan</td></tr>
  </tbody>
</table>

Keyboard Navigation

Pengguna screen reader dan banyak pengguna lain mengandalkan keyboard. Pastikan semua interaksi bisa dilakukan dengan keyboard.

Tombol Fungsi
TabBergerak ke elemen fokus berikutnya
Shift + TabBergerak ke elemen fokus sebelumnya
Enter / SpaceAktifkan elemen (button, link)
Arrow KeysNavigasi dalam komponen (tab, menu)
EscapeTutup modal/dropdown
Home / EndAwal/akhir daftar

6. WCAG Guidelines

WCAG (Web Content Accessibility Guidelines) adalah standar internasional untuk aksesibilitas web yang dikembangkan oleh W3C. Saat ini versi terbaru adalah WCAG 2.2 yang dirilis pada 2023.

Empat Prinsip WCAG (POUR)

Prinsip Penjelasan Contoh
Perceivable (Dapat Dirasakan) Informasi harus bisa dilihat atau didengar Alt text, captions video, kontras warna
Operable (Dapat Dioperasikan) UI harus bisa dioperasikan oleh semua orang Keyboard accessible, waktu cukup, tidak ada konten berkedip
Understandable (Dapat Dipahami) Konten dan UI harus mudah dipahami Bahasa sederhana, error messages jelas, navigasi konsisten
Robust (Robust/Kokoh) Konten harus bisa diinterpretasi oleh berbagai teknologi HTML valid, ARIA benar, kompatibel dengan AT

Level Conformance WCAG

Level Nama Tingkat Target
AMinimum🟒 DasarMemenuhi kebutuhan minimum aksesibilitas
AAMid-Range🟑 MenengahTarget standar untuk sebagian besar website
AAAHighestπŸ”΄ TertinggiAksesibilitas paling lengkap (sulit dicapai penuh)

Checklist WCAG Level AA

βœ… WCAG 2.2 Level AA Checklist

Perceivable:

  • βœ… Semua gambar non-dekoratif memiliki alt text
  • βœ… Video memiliki captions dan/atau audio description
  • βœ… Rasio kontras minimal 4.5:1 untuk teks normal, 3:1 untuk teks besar
  • βœ… Konten bisa di-zoom hingga 200% tanpa kehilangan fungsi
  • βœ… Informasi tidak hanya disampaikan melalui warna saja

Operable:

  • βœ… Semua fungsi bisa diakses via keyboard
  • βœ… Tidak ada keyboard trap
  • βœ… Pengguna punya cukup waktu untuk membaca dan berinteraksi
  • βœ… Konten tidak berkedip lebih dari 3 kali per detik
  • βœ… Link dan tombol memiliki ukuran minimal 24Γ—24px (WCAG 2.2)

Understandable:

  • βœ… Halaman memiliki lang attribute
  • βœ… Form memiliki label yang jelas
  • βœ… Error messages spesifik dan membantu
  • βœ… Navigasi konsisten di semua halaman

Robust:

  • βœ… HTML valid tanpa error parsing
  • βœ… Name, role, value tersedia untuk semua komponen UI
  • βœ… Status messages menggunakan ARIA live regions

Kontras Warna Minimum

Elemen Level AA Level AAA
Teks normal (< 18px)4.5:17:1
Teks besar (β‰₯ 18px / 14px bold)3:14.5:1
UI components & graphics3:13:1

7. Form yang Aksesibel

Form adalah salah satu elemen paling penting untuk aksesibilitas. Pengguna harus bisa mengisi dan mengirim form dengan keyboard dan screen reader tanpa hambatan.

Best Practices Form Accessibility

<!-- βœ… Form yang aksesibel -->
<form aria-label="Form Pendaftaran">

  <!-- Input dengan label yang terkait -->
  <div class="form-group">
    <label for="nama">Nama Lengkap <span aria-hidden="true">*</span></label>
    <input type="text"
           id="nama"
           name="nama"
           required
           aria-required="true"
           aria-describedby="nama-hint nama-error">
    <span id="nama-hint" class="hint">Masukkan nama sesuai KTP</span>
    <span id="nama-error" class="error" role="alert" aria-live="assertive">
      <!-- Error message muncul di sini -->
    </span>
  </div>

  <!-- Fieldset untuk kelompok terkait -->
  <fieldset>
    <legend>Metode Pembayaran</legend>
    <div>
      <input type="radio" id="cc" name="payment" value="cc">
      <label for="cc">Kartu Kredit</label>
    </div>
    <div>
      <input type="radio" id="bank" name="payment" value="bank">
      <label for="bank">Transfer Bank</label>
    </div>
  </fieldset>

  <!-- Select dengan label -->
  <div class="form-group">
    <label for="provinsi">Provinsi</label>
    <select id="provinsi" name="provinsi" required>
      <option value="">-- Pilih Provinsi --</option>
      <option value="jkt">DKI Jakarta</option>
      <option value="jbr">Jawa Barat</option>
    </select>
  </div>

  <!-- Checkbox -->
  <div>
    <input type="checkbox" id="agree" name="agree" required>
    <label for="agree">Saya setuju dengan syarat &amp; ketentuan</label>
  </div>

  <button type="submit">Daftar Sekarang</button>
</form>

<!-- ❌ Form TIDAK aksesibel -->
<div class="form">
  <span>Nama</span>            <!-- Bukan <label> -->
  <input type="text">           <!-- Tidak ada id, tidak ada label -->
  <div onclick="submit()">OK</div> <!-- Bukan <button> -->
</div>

Error Handling yang Aksesibel

<!-- Error summary di bagian atas form -->
<div role="alert" aria-live="assertive" class="error-summary">
  <h3>Terdapat 2 kesalahan:</h3>
  <ul>
    <li><a href="#email">Email tidak valid</a></li>
    <li><a href="#password">Password minimal 8 karakter</a></li>
  </ul>
</div>

<!-- Inline error pada setiap field -->
<div class="form-group">
  <label for="email">Email</label>
  <input type="email"
         id="email"
         aria-invalid="true"
         aria-describedby="email-error"
         class="input-error">
  <span id="email-error" class="error" role="alert">
    Format email tidak valid. Contoh: nama@email.com
  </span>
</div>

Navigasi yang baik harus bisa diakses oleh semua pengguna, baik menggunakan mouse, keyboard, maupun screen reader. Berikut beberapa pola navigasi aksesibel.

Skip Navigation Link

<!-- Skip link: muncul pertama kali saat Tab ditekan -->
<a href="#main-content" class="skip-link">Skip ke konten utama</a>

<!-- CSS -->
<style>
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px 16px;
  z-index: 10000;
  transition: top 0.2s;
}

.skip-link:focus {
  top: 0;  /* Muncul di bagian atas saat fokus */
}
</style>

Navigation dengan ARIA

<nav aria-label="Navigasi utama">
  <ul role="menubar">
    <li role="none">
      <a role="menuitem" href="/">Beranda</a>
    </li>
    <li role="none">
      <a role="menuitem"
         aria-haspopup="true"
         aria-expanded="false">
        Produk β–Ύ
      </a>
      <ul role="menu">
        <li role="none">
          <a role="menuitem" href="/produk/a">Produk A</a>
        </li>
        <li role="none">
          <a role="menuitem" href="/produk/b">Produk B</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>

<!-- Breadcrumb -->
<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Beranda</a></li>
    <li><a href="/kategori">Kategori</a></li>
    <li aria-current="page">Artikel Saat Ini</li>
  </ol>
</nav>

Multiple Navigation Landmarks

<!-- Gunakan aria-label untuk membedakan beberapa nav -->
<nav aria-label="Navigasi utama">
  <!-- Menu utama -->
</nav>

<nav aria-label="Navigasi sidebar">
  <!-- Sidebar links -->
</nav>

<nav aria-label="Breadcrumb">
  <!-- Breadcrumb -->
</nav>

<nav aria-label="Navigasi footer">
  <!-- Footer links -->
</nav>

9. Warna & Kontras

Warna memainkan peran penting dalam aksesibilitas. Pengguna dengan gangguan penglihatan (color blindness, low vision) membutuhkan kontras yang cukup dan informasi tidak boleh hanya disampaikan melalui warna.

Jenis Color Blindness

Jenis Prevalensi Kesulitan
Deuteranopia~6% laki-lakiSulit bedakan hijau-merah
Protanopia~1% laki-lakiSulit bedakan merah-hijau
Tritanopia~0.01%Sulit bedakan biru-kuning
Achromatopsia~0.003%Tidak bisa lihat warna (grayscale)

Tips Warna yang Aksesibel

<!-- ❌ JANGAN: Hanya pakai warna untuk info -->
<p style="color: red">Field wajib diisi</p>

<!-- βœ… DO: Tambahkan ikon atau teks tambahan -->
<p style="color: red">
  <span aria-hidden="true">⚠️</span>
  Field wajib diisi
</p>

<!-- ❌ JANGAN: Kontras rendah -->
<p style="color: #999; background: #fff">Teks sulit dibaca</p>

<!-- βœ… DO: Kontras cukup -->
<p style="color: #595959; background: #fff">Teks jelas terbaca</p>

<!-- βœ… Focus styles yang terlihat -->
<style>
button:focus-visible {
  outline: 3px solid #4A90D9;
  outline-offset: 2px;
}

/* Jangan hilangkan outline! */
/* ❌ *:focus { outline: none; } */
</style>

Dark Mode Accessibility

/* Dark mode dengan kontras yang baik */
:root {
  --text-primary: #1a1a1a;
  --bg-primary: #ffffff;
  --text-link: #0066cc;
}

[data-theme="dark"] {
  --text-primary: #e0e0e0;  /* Bukan putih penuh #fff */
  --bg-primary: #121212;     /* Bukan hitam penuh #000 */
  --text-link: #6db3f2;      /* Link lebih terang di dark */
}

body {
  color: var(--text-primary);
  background: var(--bg-primary);
}

/* Hindari teks putih penuh (#fff) di atas hitam (#000)
   karena bisa menyebabkan "halo effect" pada layar.
   Gunakan #e0e0e0 di atas #121212 untuk kenyamanan mata. */

10. Tools Pengujian Accessibility

Menguji aksesibilitas secara manual dan otomatis sangat penting. Berikut adalah tools yang direkomendasikan untuk memeriksa aksesibilitas website Anda.

Automated Testing Tools

Tool Tipe Fitur Utama
LighthouseChrome DevToolsAccessibility audit otomatis, scoring
axe DevToolsBrowser ExtensionDeteksi masalah WCAG, saran perbaikan
WAVEBrowser ExtensionVisual overlay masalah aksesibilitas
Pa11yCLI / CI/CDAutomated accessibility testing di pipeline
eslint-plugin-jsx-a11yESLint PluginLinting aksesibilitas untuk JSX/React
Storybook a11y addonStorybookTest aksesibilitas komponen individual

Manual Testing Checklist

πŸ” Manual Testing
  • πŸ–±οΈ Navigasi keyboard: Tab melalui semua elemen interaktif
  • πŸ”Š Screen reader test: Coba dengan NVDA (Windows) atau VoiceOver (Mac)
  • πŸ” Zoom 200%: Pastikan layout tidak pecah
  • 🎨 High contrast mode: Aktifkan mode high contrast di OS
  • πŸ“„ Hilangkan CSS: Pastikan konten tetap terbaca tanpa styling
  • πŸ“± Mobile test: Uji dengan TalkBack di Android
  • ⌨️ Focus visible: Pastikan focus indicator terlihat jelas

Contoh Pa11y CI Integration

// pa11y-ci.json
{
  "defaults": {
    "standard": "WCAG2AA",
    "timeout": 10000,
    "wait": 1000
  },
  "urls": [
    "http://localhost:3000/",
    "http://localhost:3000/artikel",
    "http://localhost:3000/kontak"
  ]
}

// package.json script
{
  "scripts": {
    "test:a11y": "pa11y-ci"
  }
}

// GitHub Actions workflow
name: Accessibility Test
on: [push, pull_request]
jobs:
  a11y:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - run: npm run serve &
      - run: npx pa11y-ci

11. Quiz Pemahaman

Uji pemahamanmu tentang HTML Semantics & Accessibility dengan menjawab pertanyaan berikut:

Pertanyaan 1: Elemen HTML mana yang sebaiknya digunakan untuk navigasi utama?

a) <nav>
b) <div class="nav">
c) <menu>
d) <navigation>

Pertanyaan 2: Apa aturan pertama penggunaan ARIA?

a) Gunakan ARIA sebanyak mungkin
b) Jangan gunakan ARIA jika bisa menggunakan elemen HTML semantik
c) ARIA hanya untuk form
d) ARIA harus selalu dikombinasikan dengan JavaScript

Pertanyaan 3: Rasio kontras minimum untuk teks normal pada WCAG Level AA adalah?

a) 2:1
b) 3:1
c) 4.5:1
d) 7:1

Pertanyaan 4: Atribut ARIA apa yang digunakan untuk menandai konten yang berubah secara dinamis?

a) aria-hidden
b) aria-expanded
c) aria-live
d) aria-label

Pertanyaan 5: Manakah yang BUKAN merupakan prinsip WCAG (POUR)?

a) Perceivable
b) Operable
c) Performant
d) Robust
πŸ” Zoom
100%
🎨 Tema