Accesibilitate site sub Legea 232/2022: ghid de implementare
Ce înseamnă Legea 232/2022 pentru un site din România: cerințele WCAG 2.1 AA în cod, cinci tipare care pică, declarația din anexa 5 și costul real.

Un magazin online cu nouă angajați și unul cu zece rulează același CSS. Diferența dintre ele nu e tehnică: pentru al doilea, cerințele de accesibilitate din Legea 232/2022 sunt obligatorii din prima zi, iar autoritatea în fața căreia răspunde e Autoritatea pentru Digitalizarea României. Primul e exceptat. Legea se uită la statul de plată înainte să se uite la cod.
Și asta e partea instabilă. Scutirea de microîntreprindere nu e o proprietate a site-ului, e o proprietate a firmei — și dispare în ziua în care semnezi al zecelea contract de muncă. În ziua aceea nu ai de adăugat o pagină, ai de refăcut interfața: contrastul moștenit din tema cumpărată, caruselul construit din div-uri, checkout-ul care nu comunică nimic unui cititor de ecran.
Textul de mai jos e despre implementare. Ce se schimbă concret în cod, cum verifici fără să plătești un audit și unde se duc banii dacă amâni.
Cadrul legal, în două paragrafe
Directiva (UE) 2019/882 — European Accessibility Act — a fost transpusă în România prin Legea nr. 232/2022 și se aplică serviciilor de comerț electronic furnizate consumatorilor începând cu 28 iunie 2025. Articolul 4 alineatul (5) scutește microîntreprinderile care prestează servicii: sub 10 angajați și cifră de afaceri anuală sau total al bilanțului sub echivalentul a 2 milioane de euro. Scutirea acoperă serviciile, nu produsele — cine fabrică sau importă hardware din categoriile acoperite rămâne în regim complet. Și, ca să nu se piardă nimeni în terminologie: microîntreprinderea din Legea 232/2022 nu e microîntreprinderea fiscală din Codul fiscal, chiar dacă numele coincide.
Supravegherea pentru comerț electronic revine Autorității pentru Digitalizarea României, prin articolul 19 alineatul (1) litera d), nu ANPC. Articolul 27 împarte sancțiunile pentru furnizorii de servicii pe trei paliere: 6.000–12.000 lei pentru nerespectarea cerințelor de accesibilitate, 7.000–15.000 lei pentru lipsa informării sau a notificării către autoritate, 5.000–10.000 lei pentru refuzul de a coopera la control. Iar articolul 26 deschide o a doua cale: nu doar consumatorii, ci și organismele publice, asociațiile sau alte entități juridice private se pot adresa direct instanței ori autorității competente. Declanșatorul nu e obligatoriu un control planificat.
Restul cadrului — cine intră exact sub lege, cum se citește scutirea, ce alte obligații legale se suprapun pe același site — e detaliat în checklist-ul legal al unui site de firmă din România. De aici încolo, articolul e despre cod.
„Conform” cu ce, mai exact
Legea nu numește WCAG. Cere ca serviciul să fie perceptibil, utilizabil, inteligibil și solid, iar prezumția de conformitate se obține prin standardele armonizate. Reperul tehnic e EN 301 549, iar versiunea la care trimite dreptul european azi e v3.2.1, publicată în martie 2021, care preia integral WCAG 2.1 nivelele A și AA pentru conținut web. Deci ținta practică pentru un site din România e WCAG 2.1 AA. Nu e o interpretare: capitolul de conținut web al standardului chiar asta conține.
Partea care se mișcă e versiunea următoare. Draftul v4.1.0, datat noiembrie 2025, actualizează cerințele din clauzele 9 (web), 10 (documente non-web) și 11 (software) ca să se alinieze la WCAG 2.2 și se așteaptă ca versiunea finală, v4.1.1, să fie referențiată în Jurnalul Oficial al Uniunii Europene în jurul lui octombrie 2026. Poziția W3C e aceeași: EN 301 549 folosește acum WCAG 2.1, iar versiunea următoare a standardului e așteptată să folosească WCAG 2.2.
De aici o divergență pe care merită s-o recunoști înainte să cumperi ceva. O parte din materialele comerciale scriu deja că „EAA impune WCAG 2.2” — afirmația merge înaintea textului. Standardul referențiat azi e cel care preia 2.1. Citirea onestă e în doi timpi: 2.1 AA e linia pe care trebuie să poți demonstra că o atingi acum, iar cele șase criterii noi de nivel A și AA aduse de 2.2 sunt sprintul următor. Sunt ieftine cât construiești și scumpe după ce ai livrat.
Contrast, focus, tastatură: stratul care se strică primul
Trei cerințe acoperă majoritatea barierelor reale și, convenabil, sunt și cele mai ieftin de reparat corect — pentru că se rezolvă o dată, la nivel de design system, nu pagină cu pagină.
Contrastul textului
Pragul e 4.5:1 pentru text normal și 3:1 pentru text mare — de la 24px, sau de la 18.66px dacă e bold. Cel mai frecvent vinovat e griul de brand moștenit dintr-un kit de UI.
Reține #767676 ca pe o constantă utilă: pe fundal alb e limita. Orice gri mai deschis pică. Dacă fundalul nu e alb, recalculează — contrastul se măsoară între cele două culori efective, nu față de o referință fixă.
Contrastul componentelor
Cerința nu se oprește la text. Elementele care transmit informație sau delimitează un control — borduri de input, iconițe funcționale, indicatorul de stare al unui checkbox — cer 3:1 față de ce e lângă ele. Aici pică aproape orice temă care folosește #ddd pentru borduri, un raport de circa 1.36:1 pe alb.
Focusul vizibil
Cea mai costisitoare linie de CSS scrisă vreodată din motive estetice:
Elimină singurul indiciu pe care îl are cineva care navighează din tastatură despre locul în care se află. Soluția modernă separă mouse-ul de tastatură prin :focus-visible, care nu declanșează inelul la click:
outline-offset nu e cosmetic: desprinde inelul de marginea butonului, ca să rămână vizibil și pe fundaluri închise. Iar inelul însuși trebuie să aibă 3:1 față de ce e sub el — un focus gri deschis pe un card gri e la fel de inutil ca absența lui.
Navigarea din tastatură
Regula scurtă: dacă se dă click pe el, trebuie să se poată ajunge la el cu Tab și să se activeze cu Enter sau Space. Un div cu handler de click nu face niciuna dintre astea.
Ruta alternativă — role="button", tabindex="0" și un handler de keydown care tratează separat Enter și Space — funcționează, dar înseamnă cod pe care îl scrii și îl testezi tu în locul browserului. Alege-o doar când chiar nu poți folosi elementul nativ.
Skip link
Un link ascuns care sare peste meniu, ca cineva care navighează din tastatură să nu treacă prin patruzeci de elemente înainte de conținut. Doar 17,1% dintre paginile principale analizate în raportul WebAIM Million pe 2026 aveau unul, iar unul din zece era rupt — ascuns într-un mod care îl făcea inaccesibil sau cu ținta inexistentă în pagină.
display: none sau visibility: hidden scot elementul din ordinea de tab — deci link-ul nu mai poate primi focus niciodată. De aici vine, în practică, unul din zece.
Formulare, imagini, structură: stratul semantic
Al doilea bloc de lucru nu se vede în captura de ecran. Se vede în ce citește un cititor de ecran cu voce tare.
Label-uri asociate, nu placeholdere
Paginile analizate de WebAIM aveau în medie 6,9 câmpuri de formular, iar o treime dintre ele — 33,1% — nu erau etichetate corespunzător, adică nu aveau nici <label>, nici aria-label, nici aria-labelledby, nici title.
Dacă designul chiar nu suportă o etichetă vizibilă, aria-label e acceptabil. Ce nu e acceptabil: un <label> fără for, plasat lângă input, care arată corect și nu spune nimic programatic.
Alt text util față de alt text bifat
16,2% dintre imaginile de pe paginile analizate nu aveau text alternativ deloc, iar 10,8% dintre cele care aveau foloseau un text discutabil sau repetitiv — „image”, „graphic”, un nume de fișier, ori exact textul de lângă. 45% dintre imaginile fără alt erau imagini care funcționau ca link, ceea ce transformă problema într-un link fără nume.
Trei reguli acoperă aproape tot:
- Imagine decorativă (fundal, separator, iconiță lângă un text care spune deja același lucru) →
alt="", gol, nu absent. - Imagine informativă → descrie ce trebuie să afle cineva care nu o vede.
alt="Scaun ergonomic gri, vedere laterală, cu suport lombar reglabil", nualt="produs-1234.jpg". - Imagine care e link → alt-ul descrie destinația, nu poza. Pentru un logo din antet:
alt="BaseTech — pagina principală".
Erori anunțate, nu doar colorate
Un mesaj de eroare care apare vizual sub câmp, în roșu, nu ajunge la cineva care nu se uită la ecran. Trebuie legat de input și anunțat activ.
aria-describedby face ca mesajul să fie citit imediat după numele câmpului. role="alert" îl anunță în momentul apariției, fără să mute focusul. Pentru mesaje care nu sunt erori — „Produs adăugat în coș”, „Se aplică filtrul” — folosește un container permanent în DOM cu aria-live="polite" și schimbă-i doar conținutul; un container injectat odată cu textul nu se anunță.
Și, complementar: culoarea nu poate fi singurul purtător de informație. Chenarul roșu are nevoie de text lângă el, iar graficul cu trei linii colorate are nevoie de etichete sau de forme diferite.
Ordinea titlurilor
Titlurile sunt mecanismul principal de navigare pentru cititoarele de ecran, iar în practică sunt tratate ca stiluri de font. Sărituri de nivel apăreau pe 41,8% dintre paginile analizate, în creștere față de 39% în 2025, iar 18,1% dintre pagini aveau mai mult de un h1.
Un singur h1 pe pagină, fără salturi peste niveluri, și <main>, <nav>, <header>, <footer> folosite ca atare. Structura corectă e gratuită la scriere și greu de retrocorectat, pentru că trece prin fiecare șablon.
Cinci tipare care pică pe site-urile românești
Raportul WebAIM nu are o defalcare pe domenii .ro, dar are una pe tehnologii — iar stack-ul tipic al unui magazin din România apare în ea. WordPress, prezent pe peste 252.000 dintre paginile analizate, avea în medie 52,8 erori detectate pe pagină; PrestaShop, 143,2 — cu 155% peste media generală de 56,1; Magento și Shopify, cu circa 35% peste medie. Bibliotecile de carusel bazate pe jQuery — Slick, Swiper, OWL Carousel — apăreau toate cu 26–32% mai multe erori decât media.
Sunt exact componentele pe care le cumperi împreună cu tema. De aici cele cinci tipare.
1. Caruselul din pagina principală, construit din div-uri. Săgețile sunt <span>-uri cu iconițe și fără nume accesibil, autoplay-ul nu are control de pauză, iar slide-urile ascunse rămân în ordinea de tab — deci focusul dispare într-un conținut invizibil. Fix: săgeți ca <button> cu aria-label, un buton de pauză real și inert pe slide-urile care nu sunt vizibile.
2. Butoanele care sunt de fapt altceva. „Adaugă în coș” ca <a href="#">, iconițele de coș, căutare și favorite ca <div> fără text. Butoane goale apăreau pe 30,6% dintre pagini și linkuri goale pe 46,3% — nu sunt cazuri exotice, sunt antetul unui magazin obișnuit. Fix: element nativ plus fie text vizibil, fie aria-label în română.
3. Griul din tema cumpărată. Text cu contrast insuficient apărea pe 83,9% dintre pagini, cu 34 de instanțe distincte pe pagină în medie — de opt ani, cea mai frecventă eroare detectabilă. Fix: corectează valorile în tokenii de design o singură dată, nu în cele patruzeci de locuri în care sunt folosite.
4. Bannerul de cookies care nu se poate închide din tastatură. Ironia e că e primul element interactiv al paginii și blochează tot ce urmează. Fix: focus mutat în banner la apariție, Escape funcțional, butoanele reale și restul paginii marcat inert cât timp e deschis — nu aria-hidden singur, care ascunde conținutul de cititorul de ecran, dar îl lasă focusabil. Partea de conformitate a aceluiași banner — categorii separate pe scop, refuz la aceeași prominență ca acceptul, ștergerea cookie-urilor la retragere — e tratată în ghidul de implementare a consimțământului pentru cookies.
5. Checkout-ul cu erori doar vizuale. Câmpuri cu placeholder pe post de etichetă, validare care colorează chenarul și afișează un text nelegat de input, iar la submit un sumar de erori care nu primește focus. Fix: perechea aria-invalid + aria-describedby de mai sus, plus mutarea focusului pe sumarul de erori după submit.
Ce nu rezolvă nimic din lista asta: bara flotantă de accesibilitate care oferă „mărește fontul” și „contrast ridicat”. Un overlay peste un DOM inaccesibil rămâne un DOM inaccesibil, cu un buton în plus — verdict pe care checklist-ul legal îl detaliază la punctul de accesibilitate.
Declarația de accesibilitate
Obligația ratată de aproape toată lumea, pentru că nu produce nimic vizibil. Articolul 13 alineatul (2) litera a) cere furnizorilor de servicii să pregătească informațiile în conformitate cu prevederile anexei nr. 5 — adică o descriere a modului în care serviciul respectă cerințele de accesibilitate, inclusă în condițiile generale sau într-un document echivalent.
Punctul important: e o obligație separată de starea reală a interfeței. Poți avea un site rezonabil accesibil și să fii în neconformitate pentru că nu ai scris nicăieri ce ai făcut. Iar palierul de sancțiune pentru lipsa informării — 7.000–15.000 lei — e mai mare decât cel pentru nerespectarea cerințelor propriu-zise.
Ce conține un document care își face treaba:
- descrierea serviciului și a modului în care e furnizat în formate accesibile;
- standardul și versiunea față de care s-a verificat — de exemplu WCAG 2.1 AA prin EN 301 549;
- data și metoda verificării: automată, manuală, cu cititor de ecran, audit extern;
- barierele cunoscute care încă există, cu ce se face cu ele și până când;
- un canal de contact pentru sesizări de accesibilitate, cu termen de răspuns.
Ultimele două puncte sunt cele care despart un document util de un text de complezență. O declarație care spune „site-ul este conform WCAG 2.1 AA” fără să fi măsurat nimic e o afirmație pe care ți-o poate contesta oricine, inclusiv o asociație care are dreptul, prin articolul 26, să sesizeze direct.
Un exemplu de transparență, cu cărțile pe masă: BaseTech e el însuși microîntreprindere prestatoare de servicii, deci intră în categoria exceptată de articolul 4 alineatul (5). Declarația publicată la pagina de accesibilitate e voluntară și scrie ce a fost implementat, nu ce scor s-ar obține la un audit — pentru că auditul nu a fost făcut. E distincția pe care merită s-o păstrezi și în textul tău: descrii implementarea, nu revendici un nivel de conformitate măsurat. Cum se scrie documentul punct cu punct, ce standard citezi și de unde vine termenul de răspuns la sesizări sunt tratate separat, în articolul despre declarația de accesibilitate și mecanismul de feedback.
Cum verifici singur, și ce nu prinde verificarea automată
Patru instrumente gratuite acoperă tot ce poți face fără buget.
Lighthouse, în DevTools din Chrome, rulează un subset de reguli axe-core și îți dă un scor. E util ca semnal de regresie și înșelător ca certificat: scorul de 100 înseamnă că nu s-a găsit nimic automat detectabil, nu că pagina e utilizabilă.
axe DevTools, ca extensie de browser, dă același motor cu rezultate mai detaliate și cu selectorul CSS al fiecărei probleme. E proiectat pentru zero fals-pozitive, deci fiecare violare raportată e reală.
Tastatura, fără mouse. Testul de zece minute care găsește cele mai multe probleme grave: pornește de la bara de adresă, apasă Tab și încearcă să duci un produs până la finalizarea comenzii. Urmărește trei lucruri — vezi mereu unde e focusul, ordinea are sens, nu rămâi blocat nicăieri.
NVDA, cititor de ecran gratuit pentru Windows (pe macOS, VoiceOver e deja instalat). Nu ai nevoie să-l stăpânești. Ajunge să parcurgi lista de titluri și lista de linkuri: dacă titlurile nu descriu structura și linkurile sună toate „citește mai mult”, ai găsit deja de lucru.
Cifra pe care nu ți-o spune scorul
Cât din problemă prinde automatizarea? Aici sursele diverg, iar divergența e chiar informația utilă. Deque, care întreține motorul axe-core, afirmă că se pot găsi automat în medie 57% dintre problemele WCAG, restul fiind marcate ca „incomplete” pentru verificare manuală. Estimările din practică sunt mai conservatoare și se grupează în jurul a 30–40% din violări prinse automat, restul de 60–70% cerând testare manuală.
Cifrele nu se contrazic atât cât pare: măsoară baze diferite — defecte documentate într-un audit față de criterii de conformitate. Concluzia e aceeași în ambele cazuri. Chiar și cifra optimistă a producătorului lasă 43% în seama judecății umane. Iar WebAIM notează explicit, în metodologia propriului raport, că absența erorilor detectate nu înseamnă că pagina e accesibilă sau conformă.
Ce rămâne obligatoriu manual: dacă alt-textul chiar descrie imaginea, dacă ordinea de focus urmează logica vizuală, dacă mesajul de eroare spune omului ce să facă, dacă subtitrările sunt corecte, dacă un flux în mai mulți pași se poate parcurge fără mouse. Niciunul dintre acestea nu e o regulă pe care o poate evalua un scanner.
Cât costă: reparație față de construit de la început
Aici circulă multiplicatori — de la „de zece ori mai scump după livrare” până la „de 2,5–4 ori” — pe care niciun material nu-i însoțește de o metodologie verificabilă: nu știi ce proiecte, ce dimensiune, ce se număra ca fiind cost de accesibilitate. Sunt cifre de argumentat, nu de bugetat. Mai util e să împarți munca pe tipuri, pentru că acolo se vede de ce diferența e reală.
Ore. Atributul lang pe <html>, alt-textele, asocierea etichetelor, ordinea titlurilor, skip link-ul, corectarea valorilor de contrast în tokenii de design. Sunt schimbări punctuale, verificabile automat, care se propagă din câteva fișiere.
Zile. Stările de focus pe toate componentele interactive, tiparul de mesaje de eroare aplicat consecvent în toate formularele, suportul de tastatură pentru dropdown-uri, taburi și acordeoane.
Săptămâni. Widget-urile custom construite din div-uri: carusel, modal, combobox, selector de dată, mega meniu. Plus cazul urât — o paletă de brand care pică pragurile la nivel de token, ceea ce înseamnă redesign, nu corectură.
De aici, singura regulă de buget care se ține: costul nu e proporțional cu accesibilitatea, ci cu cât din interfața ta e scrisă de mână. Un proiect care folosește de la început primitive accesibile — Radix, React Aria, Headless UI — golește aproape complet categoria „săptămâni”, pentru că tastatura, focusul și rolurile ARIA vin implementate și testate. Un proiect care le-a reconstruit singur plătește de două ori: o dată la scriere, o dată la remediere.
Cazul special e tema cumpărată de pe un marketplace. Când problemele sunt în structura ei, nu în conținut, înlocuirea temei costă frecvent mai puțin decât corectarea ei — și, spre deosebire de corectură, nu se pierde la următorul update. Ordinele de mărime pe categorii de proiect sunt detaliate în ghidul de costuri, iar pentru o estimare pe configurația ta concretă există configuratorul.
Și aici se închide unghiul de la început. Dacă ești exceptat azi, fereastra e deschisă: accesibilitatea intră în categoria „ore” și „zile” cât construiești. După ce angajezi al zecelea om, aceleași cerințe intră în categoria „săptămâni”, pe un cod pe care nu-l mai poți schimba liber.
Întrebări frecvente
Sunt microîntreprindere. Chiar pot ignora accesibilitatea?
Din perspectiva Legii 232/2022, scutirea de la articolul 4 alineatul (5) e reală pentru servicii. Dar e o scutire cu dată de expirare necunoscută, legată de numărul de angajați și de cifra de afaceri, nu de site. Iar dacă vinzi și produse din categoriile acoperite, scutirea nu te urmează acolo. Practic: nu ești obligat să faci un audit, dar fiecare componentă nouă construită accesibil e o componentă pe care nu o refaci mai târziu.
Un widget de accesibilitate rezolvă problema?
Nu. Bara flotantă cu „mărește fontul” și „contrast ridicat” nu produce conformitate și nu e cerută de nicio prevedere. Cerințele privesc structura interfeței — navigare din tastatură, nume accesibile, contrast, ordine logică a titlurilor, formulare etichetate. Un overlay nu schimbă niciunul dintre aceste lucruri.
Ce nivel țintesc: WCAG 2.1 AA sau 2.2 AA?
2.1 AA e ce trebuie să poți demonstra acum, fiindcă e versiunea preluată de standardul referențiat în prezent. 2.2 AA e ținta rezonabilă pentru orice se construiește de la zero în 2026, fiindcă versiunea următoare a standardului merge acolo, iar cele șase criterii noi de nivel A și AA sunt mult mai ieftin de implementat decât de retrofitat.
Lighthouse îmi dă 100 la accesibilitate. Sunt conform?
Nu. Scorul reflectă doar regulile automat verificabile, iar chiar și cea mai optimistă estimare a producătorului motorului lasă în afară aproape jumătate din probleme. Un scor de 100 e punctul de la care începe verificarea manuală: tastatură, cititor de ecran, calitatea alt-textelor și a mesajelor de eroare.
Cine răspunde dacă tema e cumpărată de pe un marketplace?
Furnizorul serviciului, adică firma care operează site-ul. Licența unei teme nu transferă obligația legală, iar autorul temei nu e parte în relația cu autoritatea. Contractual poți reglementa altfel raportul cu furnizorul, dar nu răspunderea față de ADR.
Trebuie declarație de accesibilitate dacă sunt exceptat?
Nu, obligația din anexa nr. 5 vine împreună cu obligația de fond, deci scutirea o acoperă. Rămâne utilă voluntar, cu o condiție: să descrie ce s-a implementat efectiv, nu să revendice un nivel de conformitate care nu a fost verificat.
Notă: textul de mai sus e un ghid de implementare, nu consultanță juridică. Situațiile particulare — servicii reglementate sectorial, produse cu marcaj CE, vânzări în mai multe state membre — cer analiză dedicată.
Accesibilitatea nu se termină cu un deploy, pentru că fiecare componentă nouă poate reintroduce aceleași cinci tipare. Dacă vrei un punct de plecare pe un site existent sau o interfață construită corect din prima, vezi ce acoperă serviciile de dezvoltare. Materiale conexe: conformitate legală web, hub-ul SaaS și ce trebuie verificat în footer.
Surse
- The WebAIM Million — The 2026 report on the accessibility of the top 1,000,000 home pages — WebAIM, 2026
- Final draft EN 301 549 V4.1.0 — Harmonised European Standard — ETSI, 2026
- Legea nr. 232/2022 privind cerințele de accesibilitate aplicabile produselor și serviciilor — Portal Legislativ, 2022
- Directiva (UE) 2019/882 — European Accessibility Act — EUR-Lex, 2019
Andrei Badulescu
Fondator & Software ArchitectConstruiește sisteme B2B la BaseTech — ERP la comandă, platforme SaaS, agenți AI și arhitecturi programmatic SEO. Scrie despre deciziile tehnice din spatele lor: stack, trade-off-uri și ce ține la scară.
Vezi profilul autorului →Articole conexe

Declarație de accesibilitate: conținut, feedback, termen
Cine datorează declarația de accesibilitate, ce cere anexa nr. 5, cum verifici fiecare afirmație din ea și cum rămâne adevărată după fiecare deploy.

Formular de contact GDPR: câmpuri, antibot, retenție
Formularul de contact ca sistem complet: temeiul corect, minimizarea în schema, ce declari despre antibot, cine primește mesajul și când se șterge.

Termeni și condiții: specificație de produs, nu text copiat
Termenii și condițiile ca specificație a produsului: neplată, suspendare, modificare de preț, SLA și ștergerea contului, puse față în față cu codul.
Insights pentru companii
care construiesc
Articole noi despre ERP, AI, agenți și pSEO, direct pe email. Fără spam.