Cookie

Sembra banale, ma ci sono certi aspetti dell’informatica, e quindi anche dell’HTML che di tanto in tanto vanno rivisti. Va precisato che il W3C sconsiglia vivamente l’utilizzo delle tabelle per disegnare il layout del sito. Le tabelle servono per l’introduzione dei dati, il layout si fa con i div.

Le tabelle non dovrebbero essere usate per definire la grafica dei contenuti perché potrebbe presentare problemi agli screen reader (ma anche per i bot). In più, quando usati per definire la grafica, le tabelle potrebbero forzare gli utenti a scorrere la pagina in orizzontale per vedere una tabella progettata per uno schermo più largo. Per minimizzare questi problemi gli autori dovrebbero usare i CSS per controllare il layout anziché le tabelle.

È interessante notare come il W3C non usi mai l’imperativo (dovrebbero, non dovrebbero…), loro si che conoscono le buone maniere.

Nell’articolo di oggi vediamo qualche tabella (che serva da tabella e non da layout) e le variazioni su di esse. Ognuno tragga le proprie conclusioni.

Il tag per l’intestazione: “th

Il tag “th” serve a definire l’intestazione della tabella: la prima riga e/o la prima colonna. La struttura più semplice ora caduta in disuso (senza “th“) è la seguente:

<table>  
  <tr>  
    <td>Auto</td>  
    <td>Modello</td>  
    <td>Cilindrata</td>  
  </tr>  
  <tr>  
    <td>Opel</td>  
    <td>Corsa</td>  
    <td>1.2</td>  
  </tr>  
  <tr>  
    <td>Citroén</td>  
    <td>c2</td>  
    <td>1.1</td>  
  </tr>  
</table>

Che produrrà questo risultato:

AutoModelloCilindrata
OpelCorsa1.2
Citroénc21.1

Per chi non ha grossi problemi di vista è facile capire di cosa stiamo parlando, ma chi deve appoggiarsi a uno screen reader per l’interpretazione della pagina web ne risulterebbe notevolmente svantaggiato. Per questo è stato introdotto il tag “th“, l’acronimo di “table header“. Questo tag definisce l’intestazione della tabella e la separa dai dati della tabella (“td” – table data) e si usa in questo modo:

<table>  
  <tr>  
    <th>Auto</th>  
    <th>Modello</th>  
    <th>Cilindrata</th>  
  </tr>  
  <tr>  
    <td>Opel</td>  
    <td>Corsa</td>  
    <td>1.2</td>  
  </tr>  
  <tr>  
    <td>Citroén</td>  
    <td>c2</td>  
    <td>1.1</td>  
  </tr>  
</table>

Che genererà questo risultato:

AutoModelloCilindrata
OpelCorsa1.2
Citroénc21.1

Il tag per le didascalie: “caption

Esattamente come per le fotografie, anche per le tabelle è prevista una didascalia. È possibile mostrare la didascalia sopra o sotto la tabella, l’elemento CSS che ne permette il posizionamento è “caption-side” e accetta come argomenti “top” o “bottom“. Ad ogni modo il tag “caption” non è obbligatorio, a seconda dei casi può essere usato o meno.

Se utilizzato va posizionato subito dopo il tag di apertura “table“.

<table>
  <caption>Quante auto sono parcheggiate nel mio garage?</caption>
  <tr>  
    <th>Auto</th>  
    <th>Modello</th>  
    <th>Cilindrata</th>  
  </tr>  
  <tr>  
    <td>Opel</td>  
    <td>Corsa</td>  
    <td>1.2</td>  
  </tr>  
  <tr>  
    <td>Citroén</td>  
    <td>c2</td>  
    <td>1.1</td>  
  </tr>  
</table>

Che produrrà questo risultato:

Quante auto sono parcheggiate nel mio garage?
AutoModelloCilindrata
OpelCorsa1.2
Citroénc21.1

L’attributo per sintetizzare il contenuto della tabella: “summary

In aggiunta al tag “caption” è possibile usare l’attributo “summary” (da legare al tag “table“) per spiegare brevemente il contenuto della tabella. Questa opzione non è visibile all’utente che vede la tabella, serve a chi non ci vede e utilizza uno screen reader per capire subito se la tabella lo può interessare o meno.

La struttura giusta è la seguente:

<table summary="Marca, modello e cilindrata delle automobili parcheggiate mio garage">
  <caption>Le auto del mio garage</caption>
  <tr>
    <th>Marca</th>
    <th>Modello</th>
    <th>Cilindrata</th>
  </tr>
  <tr>
    <td>Opel</td>
    <td>Corsa</td>
    <td>1.2</td>
  </tr>
  <tr>
    <td>Citroén</td>
    <td>c2</td>
    <td>1.1</td>
  </tr>
</table>

Il risultato di queste righe di codice con lo stile globalmente applicato a questo sito è questo:

Quante auto sono parcheggiate nel mio garage?
MarcaModelloCilindrata
OpelCorsa1.2
Citroénc21.1

È importante precisare che l’attributo “summary” non è visibile all’occhio di chi naviga, viene però registrato come informazione complementare dai bot e indicizza meglio la tabella e viene letto dagli screen reader per aiutare gli utenti con problemi visivi.

Intestazioni abbreviate con l’attributo “abbr

L’attributo “abbr” è un altro attributo facoltativo, che se non viene messo non pregiudica la struttura o il funzionamento della tabella. Il contenuto viene letto dagli screen reader per dare una nozione sintetica a chi ha problemi di vista, che in questo modo eviterà di sentire intestazioni con differenze minime. L’attributo “abbr” si utilizza in questo modo:

<table summary="Marca, modello e cilindrata delle automobili parcheggiate mio garage">
  <caption>Le macchine del mio garage</caption>
  <tr>
    <th abbr="Marca">La marca dell'auto</th>
    <th abbr="Modello">Il modello dell'auto</th>
    <th abbr="Cilindrata">La cilindrata dell'auto</th>
  </tr>
  <tr>
    <td>Opel</td>
    <td>Corsa</td>
    <td>1.2</td>
  </tr>
  <tr>
    <td>Citroén</td>
    <td>c2</td>
    <td>1.1</td>
  </tr>
</table>

Correlare intestazioni e dati: “scope“, “id” e “headers

Le tabelle viste fin’ora sono abbastanza banali, vediamo ora come rendere più chiaro allo screen reader la correlazione tra intestazioni e dati. Eliminiamo l’intestazione “Marca” presente nella nostra tabella, e modifichiamo le voci relative alla marca in modo da farle diventare una intestazione.

<table summary="Marca, modello e cilindrata delle automobili parcheggiate mio garage">
  <caption>Le auto del mio garage?</caption>
  <tr>
    <td></td>
    <th>Modello</th>
    <th>Cilindrata</th>
  </tr>
  <tr>
    <th>Opel</th>
    <td>Corsa</td>
    <td>1.2</td>
  </tr>
  <tr>
    <th>Citroén</th>
    <td>c2</td>
    <td>1.1</td>
  </tr>
</table>

E il risultato sarà questo:

Quante auto sono parcheggiate nel mio garage?
ModelloCilindrata
OpelCorsa1.2
Citroénc21.1

Aggiungiamo l’attributo “scope” per facilitare il lavoro allo screen reader:

<table summary="Marca, modello e cilindrata delle automobili parcheggiate mio garage">
  <caption>Le auto del mio garage</caption>
  <tr>
    <td></td>
    <th scope="col">Modello</th>
    <th scope="col">Cilindrata</th>
  </tr>
  <tr>
    <th scope="row">Opel</th>
    <td>Corsa</td>
    <td>1.2</td>
  </tr>
  <tr>
    <th scope="row">Citroén</th>
    <td>c2</td>
    <td>1.1</td>
  </tr>
</table>

L’attributo scope definisce una cella di intestazione e fornisce  informazioni di intestazione per una colonna o riga:

  • col: intestazione per la colonna
  • row: intestazione per la riga

Aggiungendo scope con il valore col alle intestazioni della prima riga andiamo a indicare che sono le intestazioni per le celle sotto elencate.

Viceversa usando row indicheremo che le intestazioni si riferiscono alle celle della riga corrispondente (a destra).

L’attributo scope supporta anche altri due valori:

  • colgroup: intestazioni per il gruppo di colonne che la contiene
  • rowgroup: intestazioni per il gruppo di righe che la contiene

Per i gruppi di colonne si utilizza l’elemento colgroup, mentre per i gruppi di righe possiamo usare thead, tfoot e tbody (che vedremo più avanti).

Un’altra tecnica per collegare i dati di una cella con le appropriate intestazione è imputare ad ogni intestazione un id univoco, poi aggiungere l’attributo header a ogni dato. Questo attributo contiene una lista separata da spazi degli id di ogni cella di intestazione che si applica ai dati di quella cella. Questa tecnica è più complicata e dovrebbe essere utilizzata solo quando ci sono dati che debbano essere collegati a più di due celle di intestazione, quando l’attributo scope è insufficiente ad esempio in tabelle molto complesse o irregolari.

Per illustrare questo esempio ho modificato la tabella.

Quante auto sono parcheggiate nel mio garage?
Dati tecniciModello
CilindrataAlimentazione
Opel1.2GPLCorsa
Citroén1.1Benzinac2

Chiaramente questo metodo diventa complicato piuttosto in fretta, meglio usare l’attributo scope quando possibile.

Gruppi di righe: thead, tfoot e tbody

Le righe della tabella possono essere raggruppate in intestazioni (thead), pié di pagina (tfoot) e uno o più corpi (tbody). Ovviamente ogni gruppo di righe deve contenere una o più righe della tabella.

Se una tabella contiene una instestazione (thead), deve apparire prima delle sezioni footer (tfoot) e body (tbody). Se decidiamo di non usare l’intestazione o il footer l’elemento tbody non è obbligatorio (ma neanche vietato, quindi lo usiamo a piacimento). La struttura della tabella con gruppi di righe somiglierà a questa:

<table>
   <thead>
      <tr></tr>
      … righe relative all'header
   </thead>
   <tfoot>
      <tr></tr>
      … righe relative al footer
   </tfoot>
   <tbody>
      <tr></tr>
      … righe relative al body
   </tbody>
   <tbody>
      <tr></tr>
      … righe relative al body della seconda tabella
   </tbody>
   … altre sezioni body se necessarie
</table>

Raggruppare le righe può essere vantaggioso per diverse ragioni:

  • semplifica applicare gli stili (CSS) delle sezioni thead, tfoot e tbody in modo indipendente, senza aggiungere classi o altro,
  • quando lanciamo la stampa di tabelle particolarmente lunghe alcuni browser (ad esempio quelli basati su gecko) ripetono l’informazione contenuta in thead e tfoot su ogni pagina stampata, rendendone più semplice la lettura,
  • separare le sezioni “header” e “footer” dal body della tabella rende possibile per i browser di visualizzare lo scrolling del solo body.

Quali benefici

Può sembrare un lavoraccio creare delle tabelle accessibili in HTML, e in effetti per le tabelle complesse lo è. A volte è impossibile poterle creare a mano. Per le tabelle più semplici, comunque usare le celle di intestazione con l’attributo scope è più veloce e semplice.

Pare ovvio che chi utilizza tecnologie assistive come ad esempio gli screen reader ottengano un beneficio assoluto dalle tabelle ottimizzate per l’accessibilità. Provare a dare un senso a una tabella di dati grande e complessa semplicemente ascoltando una voce sintetizzata può essere molto difficile o addirittura impossibile. Semplificare e renderle accessibili è un dovere.

Meno ovvio è il beneficio ottenuto dal designer e dall’utente medio, ma una tabella accessibile è piena di markup a cui poter applicare stili CSS. Una tabella accattivante e ben visualizzata può rendere la tabella più semplice da leggere per tutti.

Questo articolo è apparso per la prima volta in inglese nel 2004 ed è abbastanza impressionante il fatto che sia ancora attuale nonostante i suoi 14 anni.

Non ti basta?


TheJoe

Mantengo questo blog a livello amatoriale dal 2009. Sono appassionato di grafica, tecnologia, software Open Source. Fra i miei articoli non sarà difficile trovarne circa la musica, ed alcuni di riflessioni personali, ma preferisco indirizzare la linea del blog principalmente verso la tecnologia. Per informazioni contattami.

0 commenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.