Salt la conținut
Pandus

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

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ă atributul autofocus.
  • O cerere de închidere (de exemplu Escape) declanșează un eveniment cancel care poate fi anulat, apoi închide dialogul. Atributul closedby controlează 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.

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