Lliçó 10 de 10 · Cas pràctic · 25 min · Revisada el 26/10/2026
Cas pràctic, exercicis i llista de comprovació
Estàs llegint una lliçó oberta. Matricula't gratis per fer els tests i els exercicis, desar el teu progrés i aconseguir el certificat.
Aquesta lliçó reuneix tot el curs en un cas realista. Primer resolem pas a pas la revisió d'un component amb problemes d'ARIA; després practiques amb exercicis d'autoavaluació i acabes amb una llista de comprovació que pots fer servir en la teva feina.
El cas: la cita prèvia d'una seu electrònica
Un ajuntament ha renovat el formulari de cita prèvia de la seva seu electrònica. La persona tria oficina, filtra les franges disponibles i confirma la cita. Una veïna que fa servir NVDA amb Firefox ha enviat una queixa a través del mecanisme de comunicació que exigeix l'RD 1112/2018 (PDF, s'obre en una finestra nova): «No puc obrir els filtres, no sé quantes cites hi ha i, després de tancar l'avís de la galeta, la pàgina es queda muda». Aquest és el fragment rellevant:
<div class="btn-filtros" role="button" onclick="toggleFiltros()">Filtres</div>
<div id="filtros" class="oculto">
<span class="switch" onclick="toggleTardes(this)">Només tardes</span>
</div>
<p class="contador">12 franges disponibles</p>
<div role="option" class="hueco" onclick="elegir(this)">Dilluns 3, 17:00</div>
<div role="option" class="hueco" onclick="elegir(this)">Dilluns 3, 17:30</div>
<button aria-label="Close" onclick="cerrarAviso()"><svg>…</svg></button>
<button disabled>Confirma la cita</button>
<main aria-hidden="true">…</main> <!-- estat després de tancar l'avís -->Pas 1: inventari
Busca al codi totes les aparicions de role= i aria-, i tots els controls construïts amb elements genèrics i onclick. Aquí hi ha sis peces per revisar: el botó de filtres, l'interruptor, el comptador, les opcions d'hora, el botó de tancar l'avís i el botó de confirmar, més l'estat de <main> després de tancar l'avís.
Pas 2: inspeccionar l'arbre i escoltar
Amb el panell Accessibilitat del navegador i NVDA (amb el Visualitzador de veu actiu), recorre el formulari amb Tab i amb el mode d'exploració. Troballes:
- El
divde filtres s'anuncia com a botó en mode d'exploració, però Tab no hi arriba mai i no respon a Retorn (regles 1 i 3). Tampoc no comunica si el panell està obert. - L'interruptor és un
spansense rol ni estat: el lector diu «Només tardes» com a text pla (4.1.2). - En filtrar, el comptador canvia de 12 a 4 sense anunciar-se (4.1.3).
- Les opcions estan soltes, sense cap
listboxque les contingui ni teclat, i no indiquen quina està triada. - El botó de tancar es diu «Close» en una pàgina en català, i la icona no està amagada.
- «Confirma la cita» està inhabilitat i ningú que navegui amb teclat no sap per què.
<main>conservaaria-hidden="true"després de tancar l'avís: tot el contingut ha desaparegut per al lector, tot i que el focus continua arribant als controls.
Pas 3: corregir, del més greu al menys greu
Primer el que bloqueja completament: el contingut amagat. L'avís es refà amb inert (o amb <dialog>), i es comprova que en tancar-lo es restaura l'estat. Després, els controls: HTML natiu sempre que existeix i ARIA només per al que l'HTML no expressa. Finalment, els anuncis.
<button type="button" aria-expanded="false" aria-controls="filtros">Filtres</button>
<div id="filtros" hidden>
<button type="button" role="switch" aria-checked="false">Només tardes</button>
</div>
<p role="status" id="contador"></p>
<fieldset>
<legend>Hora de la cita</legend>
<label><input type="radio" name="hora" value="1700"> Dilluns 3, 17:00</label>
<label><input type="radio" name="hora" value="1730"> Dilluns 3, 17:30</label>
</fieldset>
<button type="button" aria-label="Tanca l'avís"><svg aria-hidden="true">…</svg></button>
<button type="submit" aria-disabled="true" aria-describedby="motivo">Confirma la cita</button>
<p id="motivo">Tria una hora per continuar.</p>Decisions explicades:
- Les opcions d'hora no necessitaven un
listbox: són una elecció única entre diverses, i els botons d'opció natius dins d'unfieldsetdonen rol, estat, agrupació i teclat sense una línia d'ARIA (regla 1). - L'interruptor sí que fa servir ARIA, perquè l'HTML no té un interruptor natiu:
role="switch"sobre un<button>, ambaria-checkedactualitzat per JavaScript i el CSS depenent de l'atribut. - El comptador és una regió
statusque existeix buida en carregar; l'script hi escriu «4 franges disponibles» després de cada filtre. - El nom «Tanca l'avís» està en català i coincideix amb el que fa (2.5.3 no s'aplica perquè no hi ha text visible, però l'idioma sí que importa).
- «Confirma la cita» es manté descobrible amb
aria-disabledi n'explica el motiu; l'script bloqueja l'enviament mentre falti l'hora. Una alternativa igual de vàlida és deixar-lo actiu i mostrar un error en prémer-lo.
Pas 4: verificar
Es repeteix el recorregut amb NVDA i Firefox i amb VoiceOver i Safari: «Filtres, botó, contret» i «expandit» en prémer-lo; «Només tardes, interruptor, desactivat»; «4 franges disponibles» sense moure el focus; les hores com a grup de botons d'opció; «Confirma la cita, botó, no disponible, Tria una hora per continuar». Es passen axe i el validador del W3C per confirmar que no queden referències trencades ni atributs no vàlids, i es respon a la veïna amb la correcció feta.
Exercicis d'autoavaluació
1. Una casella d'acceptació està feta així: <div role="checkbox" aria-checked="false" tabindex="0">Accepto les condicions</div>. Què li falta i quina és la millor solució?
Mostra la solució
Li falta el comportament: respondre a Espai i actualitzar aria-checked a cada canvi, a més de participar en l'enviament del formulari. La millor solució és la regla 1: <input type="checkbox"> amb el seu <label>, que dona tot això sense ARIA.
2. A l'enllaç «Mostra tots els tràmits →» el lector anuncia «fletxa dreta». Com ho evites sense canviar l'aspecte?
Mostra la solució
Embolcalla la fletxa en un <span aria-hidden="true">. L'enllaç continua sent enfocable i conserva el nom «Mostra tots els tràmits»; només es retira de l'arbre l'adorn.
3. Un llistat de resultats virtualitzat mostra 20 de 300 elements i el lector anuncia «1 de 20» al resultat número 141. Quins atributs ho corregeixen?
Mostra la solució
aria-setsize="300" i aria-posinset="141" (i successius) a cada element de la llista, juntament amb un text visible del tipus «Es mostren 141-160 de 300». Comprova'n el suport amb els lectors del teu públic.
4. Una intranet posa role="application" al <body> perquè funcionin les seves dreceres d'una sola tecla. Quina conseqüència té i què proposes?
Mostra la solució
El lector deixa d'interceptar el teclat a tota la pàgina: la persona no pot llegir amb fletxes ni saltar per encapçalaments. Cal treure el rol i revisar les dreceres perquè es puguin desactivar o reassignar, o actuïn només amb el focus al component, com exigeix 2.1.4 Dreceres de teclat.
5. La navegació principal d'un portal fa servir <ul role="menu"> amb role="menuitem" a cada enllaç. Què canviaries?
Mostra la solució
Trauria els rols menu i menuitem, pensats per a menús d'aplicació operats amb fletxes, i faria servir <nav aria-label="Principal"> amb una llista d'enllaços normals, marcant la pàgina actual amb aria-current="page".
Llista de comprovació
- He fet servir HTML natiu sempre que hi havia un element equivalent.
- No hi ha rols redundants, no vàlids ni abstractes.
- Cada rol de giny té focus i el teclat que descriu l'APG (s'obre en una finestra nova).
- Cada rol respecta el seu context i els seus fills obligatoris.
- Tots els controls tenen un nom accessible que conté el text visible.
- Cada estat visual té el seu atribut ARIA, i JavaScript l'actualitza.
- Totes les referències per
idexisteixen i són úniques. - No hi ha
aria-hidden="true"sobre elements enfocables ni a<body>. - Les zones fora d'ús fan servir
inert, i es restauren en acabar. - Els controls amb
aria-disabledbloquegen l'acció i n'expliquen el motiu. - Els missatges d'estat s'escriuen en regions
statusoalertque ja existien buides. - No hi ha
role="application"llevat de superfícies amb teclat propi complet. - He passat axe i el validador del W3C sense errors d'ARIA.
- He escoltat cada component amb almenys dos lectors de pantalla.
Per continuar aprenent
- WAI-ARIA 1.2 (W3C): l'especificació amb la fitxa de cada rol i atribut.
- Using ARIA (W3C): les cinc regles d'ús, amb exemples.
- ARIA in HTML (W3C): quins rols i atributs admet cada element HTML.
- ARIA Authoring Practices Guide: patrons de components amb el seu teclat i exemples.
- Understanding 4.1.2 Nom, funció i valor: intenció, beneficiaris i tècniques del criteri.
T'ha servit aquesta lliçó?
Crea el teu compte gratis i segueix el curs amb tot:
- El test d'aquesta lliçó (3 preguntes) per comprovar el que has après
- Exercicis pràctics amb pàgines reals
- El teu progrés desat: continues on ho vas deixar, des de qualsevol dispositiu
- Constància del curs amb les hores i certificat gratuït del nivell 3 quan aprovis l'examen
Entres amb el teu compte de Google o només amb el teu correu electrònic. No cal contrasenya.