Dialog modal accesibil
Actualizat 14 octombrie 2026 · Lectură de 6 min
Pop-up-uri pentru newsletter, vizualizare rapidă, ghiduri de mărimi, suprapuneri „adăugat în coș”, formulare de autentificare, preferințe pentru cookie-uri — magazinele online sunt pline de dialoguri modale, iar acestea sunt unul dintre cele mai frecvente motive pentru care utilizatorii de tastatură și de cititoare de ecran se blochează. Această pagină arată modelul corect. Face parte din seria modele de interfață accesibile.
Când folosiți un modal
APG definește un dialog drept „o fereastră suprapusă fie peste fereastra principală, fie peste o altă fereastră de dialog” și spune: „ferestrele de sub un dialog modal sunt inerte” — utilizatorii nu pot interacționa cu pagina până când dialogul se închide. Folosiți un modal când utilizatorul trebuie să termine sau să renunțe la o sarcină înainte de a continua: confirmarea unei ștergeri, autentificarea, alegerea unei variante într-o vizualizare rapidă. Pentru informații care nu blochează sarcina (un mesaj „Adăugat în coș”), un mesaj nemodal sau un mesaj de stare deranjează de obicei mai puțin.
Criterii WCAG relevante
- 2.1.1 Tastatură (A) și 2.1.2 Fără capcană pentru tastatură (A): dialogul poate fi folosit și închis cu tastatura. Păstrarea focusului în interiorul unui modal este în regulă, atâta timp cât utilizatorul îl poate părăsi.
- 2.4.3 Ordinea focusului (A): focusul intră în dialog și revine apoi pe elementul declanșator.
- 2.4.11 Focus neobstrucționat (minim) (AA): W3C notează că un modal construit corect trece întotdeauna, în timp ce suprapunerile nemodale pot ascunde elementul focalizat.
- 4.1.2 Nume, rol, valoare (A): rolul dialog și un nume.
- 1.3.1 Informații și relații (A): titlul este un heading, structura se află în cod.
- 1.4.10 Reflow (AA): dialogul încape pe un ecran îngust și la un zoom de 400 % fără derulare în două direcții.
- 2.2.1 Timp ajustabil (A): pop-up-urile nu trebuie să se închidă după un cronometru înainte ca utilizatorii să le poată citi.
Exemplu de cod
<button type="button" id="open-size-guide">Ghid de mărimi</button>
<dialog id="size-guide" aria-labelledby="size-guide-title">
<h2 id="size-guide-title">Ghid de mărimi</h2>
<table>…</table>
<button type="button" id="close-size-guide">Închide</button>
</dialog>
<script>
const dialog = document.getElementById('size-guide');
document.getElementById('open-size-guide')
.addEventListener('click', () => dialog.showModal());
document.getElementById('close-size-guide')
.addEventListener('click', () => dialog.close());
</script>
Ce face elementul nativ, conform standardului HTML:
showModal()plasează dialogul în stratul superior, blochează documentul astfel încât restul devine inert, reține elementul focalizat anterior și rulează pașii de focalizare ai dialogului, care respectă atributulautofocus.- O cerere de închidere (de exemplu Escape) declanșează un eveniment
cancelcare poate fi anulat, apoi închide dialogul. Atributulclosedbycontrolează dacă și clicurile în afara dialogului îl închid. close()readuce focusul pe elementul focalizat anterior, dacă dialogul era modal.
Dacă construiți dialogul singuri cu ARIA, urmați APG: containerul are role="dialog", aria-modal="true" și aria-labelledby care indică titlul vizibil; aria-describedby este opțional și e mai bine omis când conținutul include liste sau tabele. Trebuie apoi să faceți singuri fundalul inert, să păstrați Tab în interiorul dialogului, să tratați Escape și să restabiliți focusul.
Interacțiunea cu tastatura
Din modelul APG pentru dialog (modal):
| Tastă | Funcție |
|---|---|
| Tab | Următorul element accesibil cu Tab din dialog; de la ultimul, înapoi la primul |
| Shift + Tab | Elementul anterior din dialog; de la primul, la ultimul |
| Escape | Închide dialogul |
Focusul la deschidere: „focusul se mută pe un element conținut în dialog”, în general primul element focalizabil. Focusul la închidere: „revine pe elementul care a invocat dialogul”, cu excepția cazului în care acel element nu mai există — atunci pe un alt element care păstrează un flux de lucru logic. După „Elimină produsul”, de exemplu, focusul poate ajunge pe titlul coșului.
Greșeli frecvente în magazinele online
- Pop-up de newsletter la încărcarea paginii care fură focusul, nu are nume și nici un buton de închidere accesibil cu tastatura.
- „×” de închidere fără nume accesibil sau o pictogramă de închidere care este un
div. - Focusul rămâne în spatele suprapunerii: Tab parcurge pagina de sub fundalul întunecat.
- Fără Escape și fără o modalitate vizibilă de închidere pe mobil când dialogul este mai lung decât ecranul.
- Focus pierdut după închidere, care sare la începutul paginii în loc de butonul „Vizualizare rapidă”.
- Dialoguri de vizualizare rapidă care reconstruiesc pagina produsului cu ID-uri duplicate și formulare imbricate.
- Bannere de cookie-uri care nu sunt nici modale, nici discrete și acoperă elementul focalizat în partea de jos a ecranului — un eșec 2.4.11 conform W3C.
Ce prind verificările automate și ce testați manual
| Automat (regulă axe-core) | Ce găsește |
|---|---|
aria-dialog-name |
role="dialog" sau alertdialog fără nume |
button-name |
Butoane de închidere fără nume |
aria-hidden-focus |
Elemente focalizabile în conținut ascuns cu aria-hidden="true" |
aria-hidden-body |
aria-hidden="true" pe elementul body |
aria-valid-attr-value |
aria-labelledby care indică un ID inexistent |
color-contrast, target-size |
Contrast scăzut și ținte mici într-un dialog deschis |
Toate sunt fișe în biblioteca noastră de reguli. Scanarea săptămânală vede pagina așa cum se încarcă: un dialog închis nu este testat, un pop-up care se deschide singur este. Cu extensia de browser puteți deschide dialogul și apoi rula verificarea. Testarea manuală: deschideți dialogul cu tastatura, parcurgeți-l cu Tab până la capăt și înapoi, apăsați Escape, verificați unde ajunge focusul, măriți la 400 % și ascultați cum îl anunță un cititor de ecran. Pașii sunt în cum testați WCAG.
Rulați verificarea gratuită a unei pagini. Este o verificare automată, nu un audit complet, și nu constituie consultanță juridică.
Întrebări frecvente
Ce face un dialog modal să fie accesibil?
Focusul intră în dialog când acesta se deschide, Tab și Shift + Tab rămân în interiorul lui, Escape îl închide, focusul revine pe butonul care l-a deschis, conținutul din spate este inert, iar dialogul are un nume dat de titlul său vizibil.
Ar trebui să folosesc elementul HTML dialog?
Pentru un modal, elementul dialog deschis cu showModal() face o mare parte din muncă: standardul HTML îl pune în stratul superior, face restul documentului inert, gestionează focusul inițial și îl închide la o cerere de închidere, de exemplu Escape. Testați-l cu browserele și cititoarele de ecran pe care le folosesc clienții dvs.
Unde trebuie să ajungă focusul când se deschide un dialog?
APG spune că focusul se mută pe un element din interiorul dialogului, în general primul element focalizabil. Pentru un text lung poate fi mai bine să focalizați începutul conținutului. Cu elementul dialog îl alegeți prin atributul autofocus.
Este un banner de cookie-uri un dialog modal?
Doar dacă este construit ca unul. Un banner nemodal nu trebuie să ascundă elementele focalizate: W3C spune că un banner de cookie-uri fix nu îndeplinește 2.4.11 Focus neobstrucționat dacă acoperă complet o componentă care primește focusul.
Poate o verificare automată să testeze un modal?
Parțial. Găsește dialoguri fără nume, butoane de închidere fără nume și elemente focalizabile ascunse cu aria-hidden. Nu poate testa mutarea focusului, capcana de focus sau Escape, iar un dialog închis nu este verificat deloc.
Surse
- W3C WAI, APG Dialog (Modal) pattern: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
- WHATWG, HTML Living Standard, the dialog element: https://html.spec.whatwg.org/multipage/interactive-elements.html#the-dialog-element
- W3C, Understanding 2.4.11 Focus Not Obscured (Minimum): https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html