Modal
Jendela yang muncul di atas halaman utama atau di atas modal lain. Selama modal terbuka, konten di belakangnya tidak bisa diakses sampai modal ditutup.
Modal yang Aksesibel (WCAG 2.2)
<button type="button" id="open-dialog">Hapus alamat</button>
<!-- showModal() makes the rest of the page inert, keeps focus inside
the dialog and closes it on Escape. -->
<dialog id="delete-dialog" aria-labelledby="delete-title" aria-describedby="delete-desc">
<div class="header">
<h2 id="delete-title">Hapus Alamat?</h2>
<button type="button" class="close" aria-label="Tutup">
<svg aria-hidden="true">…</svg>
</button>
</div>
<p id="delete-desc">Kamu akan menghapus alamat ini secara permanen.</p>
<div class="actions">
<!-- Initial focus goes to the safe choice -->
<button type="button" value="cancel" autofocus>Tidak Jadi</button>
<button type="button" value="confirm">Ya, Hapus</button>
</div>
</dialog>
<script>
const trigger = document.getElementById('open-dialog')
const dialog = document.getElementById('delete-dialog')
trigger.addEventListener('click', () => {
document.documentElement.style.overflow = 'hidden' // no scrolling behind
dialog.showModal()
})
dialog.querySelectorAll('button').forEach((button) => {
button.addEventListener('click', () => dialog.close())
})
// Runs for every way of closing, including Escape
dialog.addEventListener('close', () => {
document.documentElement.style.overflow = ''
trigger.focus()
})
</script>Membuat Modal yang Aksesibel
- Pastikan fokus keyboard berpindah ke dalam modal saat dibuka
- Sediakan cara menutup yang mudah (tombol tutup dan tombol Esc)
- Nonaktifkan interaksi dengan konten di belakang modal
- Berikan judul modal yang jelas dan informatif
- Kembalikan fokus ke elemen pembuka setelah modal ditutup
Modal yang Tidak Aksesibel (Harap Dihindari)
Contoh tidak aksesibel. Jangan ditiru.
<button type="button" onclick="openModal()">Hapus alamat</button>
<!-- A plain div: no dialog role, no name, focus never moves into it,
Escape does nothing and the page behind it stays interactive. -->
<div class="overlay" style="display: none">
<div class="modal">
<div class="header">
<!-- A p, not a heading -->
<p class="title">Hapus Alamat?</p>
<!-- An icon in a span: not focusable, no name -->
<span class="close" onclick="closeModal()">✕</span>
</div>
<p>Kamu akan menghapus alamat ini secara permanen.</p>
<div class="actions">
<div class="btn" onclick="closeModal()">Tidak Jadi</div>
<div class="btn primary" onclick="closeModal()">Ya, Hapus</div>
</div>
</div>
</div>Contoh Implementasi Modal yang Tidak Aksesibel
- Fokus keyboard tidak dipindahkan ke dalam modal dan tidak dijaga di sana, sehingga pengguna bisa mengakses konten di belakang modal yang seharusnya tidak aktif
- Tidak ada cara menutup yang mudah: ikon tutup tidak bisa difokus dan tidak bernama, dan tombol Esc tidak berfungsi
- Konten di belakang modal tidak dinonaktifkan, sehingga masih bisa diinteraksikan saat modal terbuka
- Fokus tidak dikembalikan ke elemen pemicu setelah modal ditutup, sehingga pengguna keyboard kehilangan posisinya
- Tidak ada peran dialog, judul yang bisa dibaca pembaca layar, maupun struktur konten yang tepat di dalam modal