Dialog modal modern sering kali mendukung "penutupan ringan", yang memungkinkan pengguna menutup dialog dengan mengklik atau mengetuk latar belakang (area di luar dialog). Atribut closedby menyediakan cara deklaratif untuk mengaktifkan perilaku ini tanpa JavaScript kustom.
Penerapan
Untuk mengaktifkan penutupan ringan:
- Tambahkan
closedby="any"ke elemen<dialog>. - Buka dialog menggunakan
dialog.showModal().
Nilai Atribut
any: Mengaktifkan penutupan ringan (mengklik latar belakang), "permintaan tutup" (tombolEsc), dan mekanisme developer (misalnya,dialog.close()).closerequest: Hanya mengaktifkan "permintaan tutup" dan mekanisme developer. Ini adalah setelan default untuk dialog modal.none: Hanya mekanisme developer yang dapat menutup dialog.
Menata Gaya Backdrop
Saat dialog dibuka sebagai modal menggunakan showModal(), browser akan membuat elemen pseudo ::backdrop. Backdrop ini menutupi seluruh area pandang dan berada tepat di belakang dialog.
/* Style the backdrop to indicate the dialog is modal */
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px); /* Optional: add blur for modern browsers */
}
Contoh
<!-- MANDATORY: Use closedby="any" to enable light-dismiss behavior -->
<dialog id="myDialog" closedby="any" aria-labelledby="dialogTitle">
<form method="dialog">
<h2 id="dialogTitle">Feedback</h2>
<p>Click outside this box or press Esc to dismiss.</p>
<button type="submit">Close</button>
</form>
</dialog>
<button onclick="document.getElementById('myDialog').showModal()">Open Dialog</button>
Batasan & Aksesibilitas
- WAJIB: Gunakan
closedby="any"untuk mengaktifkan penutupan ringan secara deklaratif. - WAJIB: Selalu buka dialog modal dengan
showModal(). Hal ini memastikan dialog berada di lapisan atas, fokus terjebak, dan tombolEscditangani. - LAKUKAN: Gunakan
aria-labelledbyatauaria-labeluntuk memberikan label aksesibilitas untuk dialog. - JANGAN: Gunakan
closedbyuntuk dialog non-modal (dibuka denganshow()), karena tidak memiliki latar belakang dan tidak akan memicu penutupan ringan. - JANGAN: Menggunakan peristiwa
clickuntuk logika penting yang seharusnya terjadi sebelum penutupan; sebagai gantinya, proses peristiwacloseataucancel.
Strategi penggantian
WAJIB: Untuk browser yang belum mendukung closedby, Anda harus menerapkan penggantian untuk penutupan ringan dengan memeriksa apakah klik terjadi di luar batas konten dialog menggunakan skrip berikut:
const dialog = document.querySelector('dialog');
// Fallback for browsers without closedby support
if (!('closedBy' in HTMLDialogElement.prototype)) {
dialog.addEventListener('click', (event) => {
// 1. When clicking the backdrop, the event target is the dialog element itself.
// Ignore clicks where the target is a child element inside the dialog.
if (event.target !== dialog) return;
// 2. Check if the click coordinates fall within the dialog's content box.
// This distinguishes between a click on the backdrop vs a click on the dialog's background/padding.
const rect = dialog.getBoundingClientRect();
const isDialogContent = (
rect.top <= event.clientY &&
event.clientY <= rect.top + rect.height &&
rect.left <= event.clientX &&
event.clientX <= rect.left + rect.width
);
if (isDialogContent) return;
// 3. Since the click was outside the content area (on the backdrop), manually close the dialog.
dialog.close();
});
}