Com fer accessibles les taules complexes

Les taules HTML tenen mala fama. Sovint es consideren dolentes per a l’accessibilitat, mala pràctica i antiquades.

Aquesta fama només és justa quan fem servir les taules per a la maquetació. La majoria de llocs web moderns no ho fan, però la majoria de correus electrònics sí. Les taules tenen valor semàntic (significat) i comportament funcional. Les taules funcionen bé per a dades en files i columnes. No funcionen bé per a la maquetació.

Pots fer servir role="presentation" per eliminar el valor semàntic i el comportament funcional d’una taula. Tot i així, l’ordre del contingut al DOM ha de continuar tenint sentit.

Vegem un exemple d’una taula amb informació d’inventari d’una petita fleca:

Inventari setmanal per categoria
CategoriaArticlePreusStockEstat
Cost unitariPreu de vendaEn stockNivell de reposició
PansBaguette$0.65$3.254220OK
Pa de massa mare$0.90$4.751518Baix
Pa de sègol$0.85$4.502715OK
BrioixeriaCroissant de mantega$0.55$2.956025OK
Danesa de cireres$0.70$3.50812Baix
PastissosPorció de pastís de pastanaga$1.10$4.951810OK
Porció de pastís de formatge$1.25$5.252210OK
Totals192 unitats110 unitats2 articles baixos

No sembla malament, oi? El CSS fa que les parts siguin fàcils de distingir, i la maquetació té sentit.

Aquest és el problema principal. La informació important, com les relacions i l’estructura, depèn només dels estils visuals i la posició. Les persones que fan servir tecnologia d’assistència no poden accedir a aquesta informació.

Al final d’aquest article, trobaràs la mateixa taula amb tot el que li falta a la primera versió.

Anem pas a pas.

Cel·les d’encapçalament

Aquest és el canvi més fàcil de fer. Totes les cel·les de la primera taula fan servir l’etiqueta de cel·la de dades, <td>. Però l’HTML també té una etiqueta de cel·la d’encapçalament, <th>, per a les cel·les que actuen com a encapçalaments.

Fes servir l’atribut scope per marcar una cel·la d’encapçalament com a encapçalament de columna (scope="col") o encapçalament de fila (scope="row"). Això et dona encapçalaments a la part superior de cada columna, i un encapçalament a l’inici de cada fila.

Grups de files

Una taula pot tenir tant grups de columnes com grups de files. L’atribut scope també accepta els valors colgroup i rowgroup per a aquests casos.

Hi ha 3 grups de files principals: la capçalera de la taula (<thead>), el cos de la taula (<tbody>) i el peu de la taula (<tfoot>). Són especialment útils per a taules grans.

En el nostre exemple:

  • Els encapçalaments superiors van a la capçalera de la taula.
  • Les dades dels productes van al cos de la taula.
  • Els totals van al peu de la taula.

Això facilita la navegació entre les parts principals.

Títol

Aquesta part importa. Un títol (caption) descriu el contingut de la taula perquè les persones puguin decidir si necessiten o volen llegir les dades.

Aquí tens diverses opcions. Pots fer servir:

  • Un <caption> (o <figcaption> si la taula està dins d’un <figure>)
  • Text, com un paràgraf, col·locat abans de la taula
  • Text en un altre element, vinculat amb l’atribut aria-describedby

Aquests mètodes funcionen igual de bé. Fes servir només un.

Un avantatge de <caption>: hi pots imbricar un element <details>, amb informació addicional en un desplegable <summary>, o afegir text que estigui ocult visualment però que els lectors de pantalla puguin continuar llegint. Vaig fer servir aquest segon enfocament en l’exemple al final de l’article. Dona a tothom una etiqueta curta i visible, i als usuaris de lectors de pantalla un text més llarg amb més context.

Nota: l’atribut summary a l’element <table> és obsolet a l’HTML Living Standard. No el facis servir.

Encapçalaments multinivell

Aquesta part marca la diferència més gran per a les persones que fan servir tecnologia d’assistència, especialment en taules complexes.

En el nostre exemple, tant les columnes com les files tenen diversos nivells d’encapçalament. Això pot semblar complicat, però la solució és senzilla.

Primer, afegeix un atribut id únic a cada cel·la d’encapçalament. Després afegeix un atribut headers a cada cel·la de dades. Enumera totes les cel·les d’encapçalament amb què es relaciona, tant de columna com de fila, a tots els nivells.

Per exemple, la cel·la amb el preu de venda de la baguette inclou: headers="row-breads row-baguette col-pricing col-retail". Això permet que els lectors de pantalla anunciïn tots els encapçalaments relacionats amb aquesta cel·la.

Conclusió

Les taules accessibles no són difícils de construir. El marcatge pot arribar a ser detallat, ja que estàs vinculant moltes cel·les amb molts encapçalaments. Però és senzill d’implementar. I converteix una experiència lenta i frustrant —desplaçar-se per dades interminables sense context— en una font d’informació clara i utilitzable.

Inventari setmanal per categoria Enumera el cost unitari, el preu de venda, les existències actuals i el nivell de reposició de cada article de la fleca, agrupats per categoria de producte, amb els totals a l’última fila.
CategoriaArticlePreusStockEstat
Cost unitariPreu de vendaEn stockNivell de reposició
PansBaguette$0.65$3.254220OK
Pa de massa mare$0.90$4.751518Baix
Pa de sègol$0.85$4.502715OK
BrioixeriaCroissant de mantega$0.55$2.956025OK
Danesa de cireres$0.70$3.50812Baix
PastissosPorció de pastís de pastanaga$1.10$4.951810OK
Porció de pastís de formatge$1.25$5.252210OK
Totals192 unitats110 unitats2 articles baixos