Adriano - racconti e altro

Liste e tabelle

Concluderò il mio viaggio nel magico mondo della impaginazione degli e-books, parlando di un caso più specifico, ma non per questo meno utile: come modificare liste e tabelle. Se state lavorando a un normale testo di prosa, è molto probabile che questo capitolo non vi servirà mai; nel caso di guide, manuali o testi scientifici, invece, liste e tabelle saranno ospiti molto più frequenti nel vostro testo e potrebbe essere utile sapere come trattarle. In ogni caso, vedremo adesso come realizzare e modificare, a nostro piacimento, le liste e le tabelle in uno EPUB.

8-1 Modificare le liste

Come probabilmente saprete (o almeno me lo auguro), esistono due tipi di lista, in HTML: la lista ordinata e la lista non ordinata. La lista ordinata è contenuta in un tag <ol> ed è una lista in cui ogni elemento è introdotto da un numero progressivo; la lista non ordinata è contenuta in un tag <ul> ed è una lista in cui ogni elemento è introdotto da un simbolo grafico (di solito un pallino). Gli elementi di una lista, invece, sono contenuti ciascuno in un tag <li>. Di conseguenza, questo è un esempio di lista ordinata
<ol>
  <li>Primo elemento</li>
  <li>Secondo elemento</li>
  <li>Terzo elemento</li>
  <li>Quarto elemento</li>
</ol>

, che darà il seguente risultato:

  1. Primo elemento
  2. Secondo elemento
  3. Terzo elemento
  4. Quarto elemento
E questo è un esempio di lista non ordinata
<ul>
  <li>Primo elemento</li>
  <li>Secondo elemento</li>
  <li>Terzo elemento</li>
  <li>Quarto elemento</li>
</ul>

, che darà invece il seguente risultato:
  • Primo elemento
  • Secondo elemento
  • Terzo elemento
  • Quarto elemento

Praticamente uguali, a parte il tag che le contiene: cambia però il modo in cui saranno riprodotte sullo schermo. La quasi totalità dei dispositivi, come impostazione di base, precederà ogni voce di una lista ordinata con un numero e ogni voce di una lista non ordinata con un pallino. In alcuni casi, una soluzione di questo tipo può andarci bene; in altri casi, però, potremmo desiderare qualcosa di più bello per le nostre liste, qualcosa che colpisca maggiormente l’occhio del lettore. Vediamo dunque quali proprietà si possano modificare, usando il CSS.

Il primo attributo che ci interessa è list-style-type.

Per le liste non ordinate, ossia il tag <ul>, abbiamo tre possibili valori da assegnare a questo attributo:

  1. disc, che mostrerà uno normale pallino pieno;
  2. round, che mostrerà un pallino vuoto;
  3. square, che mostrerà un quadrato pieno.

Per le liste ordinate, ossia il tag <ol>, abbiamo invece sei possibili valori di base:

  1. decimal, che corrisponde a una normale numerazione da 1 in poi;
  2. decimal-leading-zero, che corrisponde a una normale numerazione, ma con uno 0 che precede ogni numero (da 01 in poi, insomma);
  3. upper-alpha, che corrisponde a una numerazione alfabetica, a lettere maiuscole (da A in poi);
  4. lower-alpha, che corrisponde a una numerazione alfabetica, a lettere minuscole (da a in poi);
  5. upper-roman, che corrisponde a una numerazione in numeri romani maiuscoli (da I in poi);
  6. lower-roman, che corrisponde a una numerazione in numeri romani minuscoli (da i in poi).

Esistono poi altre varianti locali, che permettono ad esempio di utilizzare le lettere dell’alfabeto greco o di alfabeti non latini: ne potete trovare una lista a questa pagina:
developer.mozilla.org/en-US/docs/CSS/list-style-type

Questa proprietà può essere assegnata sia all’intera lista, ossia ai tag <ol> e <ul>, sia a singole voci di una lista (cioè a singoli tag <li>, mediante classi di stile). Inoltre, se vogliamo nascondere questi elementi grafici, possiamo utilizzare la proprietà
list-style-type: none;
, che nasconderà pallini, numeri e quanto altro.

Un secondo attributo, che possiamo voler modificare, è list-style-position, che determina il collocamento della decorazione, rispetto alle varie voci della lista. Assegnando una particolare classe di stile al tag <li> e modificando il valore di padding-left, possiamo variare la distanza tra il simbolo (pallino, numero o altro) e la voce della lista; list-style-position ci facilita almeno in parte il lavoro, permettendoci di stabilire se il simbolo dovrà essere esterno o interno alla voce della lista.

I valori a nostra disposizione, per questo attributo, sono due:

  1. outside, che posiziona il simbolo all’esterno della voce, come se appartenessero a due colonne diverse (lo stile di base di ogni browser);
  2. inside, che posiziona il simbolo all’interno della voce, come se fossero su una stessa colonna.

Probabilmente non sarà un grande aiuto, ma per aggiustamenti più precisi bisognerà utilizzare i valori di margin-left e padding-left, come in parte dicevo. Se volete, ad esempio, azzerare il rientro che ogni dispositivo pone accanto agli elementi di una lista, dovrete azzerare sia margin-left che padding-left per i tag <ul> e <ol>.

Infine, la proprietà list-style-image ci permette di mandare al diavolo pallini, numeri o altro, per sostituirli con una immagine a nostra scelta. Il suo funzionamento è simile a quello di background-image, in quanto ci richiede di specificare, come attributo, la posizione in cui si trova l’immagine da utilizzare.

Ad esempio, se vogliamo utilizzare l’immagine “Lista.jpg”, collocata nella cartella Images, dovremo scrivere
list-style-image: url(../Images/Lista.jpg);
e assegnare questa proprietà a un tag <ul>: in pratica, costruiremo una lista non ordinata, usando però i simbolo da noi scelti, invece di cerchi o quadrati. Questa proprietà, però, non ci permetterà di esercitare un grande controllo sulla posizione dei simboli, per cui dovremo procedere per tentativi, se la vogliamo utilizzare.

8-2 Modificare le tabelle

Le tabelle hanno avuto una vita curiosamente complicata, nel mondo dello HTML. Nate come puro e semplice strumento per organizzare i dati, alla fine degli anni ’90 hanno conosciuto una diffusione abnorme, come strumento per impaginare i siti web: le pagine erano strutturate come tabelle, dove i vari elementi prendevano il posto dei dati, e non di rado trovavamo tabelle all’interno di tabelle, in un sistema a scatole cinesi che pareva progettato da Escher dopo una pesante sbronza. Oggi, grazie anche alla introduzione del CSS, come strumento principe per la impaginazione, le tabelle sono tornate al proprio ruolo naturale, ossia di spazio in cui ordinare i dati. È in questa forma che ne discuterò, nella presente sezione.

In HTML, e in XHTML, una tabella è racchiusa dai tag <table> e </table>, che segnano l’inizio e la fine degli elementi da includere nella tabella: ciò che si trova nel mezzo, invece, è alquanto variegato e dipende da un discreto numero di altri tag, in parte obbligatori e in parte opzionali. Ad esempio, questa è la struttura di una tabella con tutti gli annessi e connessi:
<table>
  <caption>
    Esempio di tabella.
  </caption>
  <colgroup>
    <col class=”prima”>
    <col class=”seconda”>
    <col class=”terza”>
  </colgroup>
  <thead>
    <tr>
      <th scope=”col”>Primo</th>
      <th scope=”col”>Secondo</th>
      <th scope=”col”>Terzo</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1-1</td>
      <td>1-2 </td>
      <td>1-3</td>
    </tr>
    <tr>
      <td>2-1</td>
      <td>2-2</td>
      <td>2-3</td>
    </tr>
  </tbody>
</table>

Otterremo questo risultato, con un poco di CSS:

Esempio di tabella.
Primo Secondo Terzo
1-1 1-2 1-3
2-1 2-2 2-3

Non tutti questi tag sono strettamente necessari: per una semplice tabella, senza tante pretese, possiamo accontentarci di utilizzare i tag <tr>, che delimitano le righe di una tabella, e i tag <td>, che delimitano le celle all’interno di una riga. A ogni modo, diamo una rapida occhiata ai vari tag, giusto per farci una idea delle rispettive funzioni: per un’analisi più accurata, vi rimando a un qualsiasi manuale di HTML.

<caption> racchiude una eventuale descrizione della tabella, che possiamo sistemare in alto o in basso rispetto alla tabella stessa. Per deciderne la posizione, assegneremo a questo tag una proprietà align: top; (se lo vogliamo al di sopra della tabella), oppure align: bottom; (se lo vogliamo al di sotto della tabella).

<colgroup> è un tag che possiamo utilizzare, per assegnare a ogni colonna della tabella una classe di stile diversa, cosa che può tornare molto utile se, ad esempio, vogliamo assegnare a ogni colonna una larghezza su misura. In questo caso, all’interno del tag <colgroup> inseriremo tanti tag <col> quante sono le colonne della tabella: a ogni tag <col>, poi, assegneremo una classe di stile.

<thead> è il tag che racchiude la testa della colonna, ossia quella riga in cui sono indicati i nomi delle varie colonne: spesso ma non necessariamente è in un colore diverso, rispetto al corpo della tabella, e di norma ci dice cosa siano i dati contenuti nelle rispettive colonne.

<tbody> è il tag che racchiude il corpo della tabella, ossia i dati veri e propri.

<tr> è il tag che delimita una riga della colonna: di norma, ne troveremo uno all’interno del tag <thead> e un numero variabile all’interno del tag <tbody> (un tag <tr> per ogni riga da cui la nostra tabella sarà composta).

<th> rappresenta i vari rettangoli, da cui una riga di tabella è composta (le celle): è usato solo nel tag <thead>. Se una tabella ha cinque colonne, nel tag <thead> troveremo 5 tag <th>, all’interno di in un tag <tr>.

<td> rappresenta i vari rettangoli, da cui una riga di tabella è composta (di nuovo, le celle): è identico a <th>, ma è usato nel tag <tbody>. Se una tabella ha cinque colonne, nel tag <tbody> troveremo 5 tag <td> per ogni tag <tr> che abbiamo.

Dopo questo breve esame dei tag che compongono una tabella, vediamo come sia possibile lavorare sulla tabella stessa, usando il CSS. In linea generale, non troveremo molte nuove proprietà, specifiche per le tabelle, ma vedremo come applicare a una tabella le proprietà discusse nei capitoli precedenti. Proprietà come il colore del testo, il tipo di font, eccetera, possono essere applicate normalmente e non necessitano di spiegazioni particolari; altre proprietà, come i margini o l’allineamento del testo, necessitano invece di qualche riga di spiegazione. Procediamo dunque col lavoro.

Prima di tutto, il bordo. Possiamo circondare la nostra tabella con un bordo definito, proprio come lo possiamo fare per ogni altro elemento: in questo caso, assegneremo una proprietà border al tag <table>, per rinchiudere la tabella intera, ma anche ai tag <tr>, <th> e <td>, per disegnare un bordo anche attorno ai vari pezzi di tabella. Aggiungere i bordi, però, potrebbe causare spiacevoli effetti collaterali, sul piano grafico: i bordi confinanti potrebbero sovrapporsi, oppure potrebbero rimanere buchi tra le varie celle di una tabella. Abbiamo due soluzioni a questo.

La proprietà border-spacing permette di definire lo spazio da lasciare tra una cella e l’altra. Se non vogliamo che ci siano spazi, basterà assegnare un valore pari a zero
border-spacing: 0;
e gli spazi tra le celle saranno eliminati. Se invece vogliamo uno spazio tra le celle, al posto dello zero assegneremo un valore numerico, corrispondente alla dimensione dello spazio ed espresso in una delle solite unità di misura. Ad esempio,
border-spacing: 3px;
lascerà uno spazio di 3 pixel tra ogni cella della nostra tabella.

La proprietà border-collapse è opposta a border-spacing: assegnandola a una tabella, i bordi di elementi confinanti collasseranno, trasformandosi in un bordo solo. Se assegniamo border-collapse, dunque, qualsiasi valore potremmo aver assegnato a border-spacing non avrà effetto. I possibili valori di border-collapse sono due: separate e collapse.

Tra questi due valori,
border-collapse: separate;
è la norma per ogni tabella, per cui non è necessario specificarlo: i bordi saranno separati. Invece, impostare la proprietà
border-collapse: collapse;
ci permetterà di far collassare assieme i bordi, per gli elementi di una tabella a cui lo assegneremo. Di norma, tanto border-spacing quanto border-collapse sono assegnati al tag <table>, ma si escludono a vicenda: o assegnate uno, oppure assegnate l’altro.

Sempre al tag <table> possiamo assegnare una proprietà margin, se vogliamo controllare la distanza tra la tabella e il testo precedente o successivo: funziona come qualsiasi altro elemento, in questo senso. Più interessante, invece è il metodo per controllare l’ampiezza delle celle e la posizione dei dati contenuti nelle suddette celle.

Per determinare la quantità di spazio vuoto tra il bordo di una cella e il suo contenuto, dovremo impostare la corrispondente proprietà padding per i tag <td> e <th>: il tag <td> per il corpo della tabella e il tag <th> per la sua intestazione. Ad esempio, la regola
td {
  padding: 5px 10px;
}

assegnerà a tutti i tag <td> un margine interno superiore e inferiore di 5 pixel, mentre il margine interno destro e sinistro sarà di 10 pixel: questi margini interni saranno posizionati tra il bordo della cella e il suo contenuto. Abbiamo già visto come funzioni questo attributo in un capitolo precedente, per cui non mi dilungherò qui.

Per posizionare il contenuto di una cella, invece, le proprietà che ci interessano sono text-align e vertical-align: la prima la conosciamo già e ci permette di determinare se il contenuto delle celle sarà allineato a destra, a sinistra o al centro, mentre la seconda proprietà, vertical-align, ci è nuova e merita pertanto qualche parola in più. Normalmente, i dispositivi di lettura allineano il contenuto di una cella al suo centro, sul piano verticale, a prescindere da quanto spazio ci sia in alto o in basso. Se questa soluzione non ci va bene e vogliamo che il contenuto delle celle sia in una posizione diversa, ossia più vicina al bordo alto o al bordo basso, dovremo assegnare un altro valore all’attributo vertical-align.

I valori a nostra disposizione, per l’attributo vertical-align, sono quattro: top, middle, bottom, baseline. Top spingerà il contenuto verso il margine alto della cella, bottom lo spingerà verso il margine basso, middle lo sistemerà al centro (impostazione base per ogni dispositivo), baseline porterà il contenuto della cella verso l’alto (quasi come top), ma allineandolo alla prima linea di testo nelle celle limitrofe. Di fatto, top e baseline producono raramente un risultato diverso e solo quando le celle contengono parecchio testo: se siete particolarmente perfezionisti, oppure se soffrite di un disturbo ossessivo compulsivo, allora potreste notare subito le differenze tra le due proprietà, ma sappiate che non tutti i vostri lettori se ne accorgeranno.

Oltre a queste, possiamo assegnare a una tabella e al suo contenuto tutti o quasi i normali attributi, utilizzabili per il testo. In particolare, possiamo colorare lo sfondo delle celle, magari in modo alternato, così da renderne più semplice la fruizione ai lettori: alternare il colore dello sfondo è molto utile, se la tabella è piuttosto corposa o i dati sono parecchi. Per questo effetto alternato, possiamo ricorrere a uno pseudoelemento un poco particolare, ossia :nth-of-type().

Questo pseudoelemento ci permette di selezionare le celle in modo alternato, a seconda di cosa inseriamo tra le parentesi: :nth-of-type(odd) selezionerà tutte le celle dispari, mentre :nth-of-type(even) selezionerà tutte le celle pari. Ad esempio,
tr:nth-of-type(odd) {
  background-color: yellow;
}

selezionerà tutte le righe (tag <tr>) dispari della tabella e ne colorerà lo sfondo di giallo. In questo modo, le righe avranno un colore diverso tra loro: il normale colore dello sfondo per le righe pari, il giallo per le righe dispari.

Se invece usiamo
td:nth-of-type(even) {
  background-color: yellow;
}

, allora saranno le colonne a essere colorate in modo alternato, invece delle righe: abbiamo infatti assegnato lo pseudoelemento al tag <td>, invece che a <tr>. Naturalmente, se ci interessa colorare in modo diverso le colonne, possiamo anche assegnare una classe per ogni colonna ai tag <col> e poi impostare lo sfondo che vogliamo per quella classe, così da avere ogni colonna di un colore diverso. Non è detto che il risultato sarà particolarmente piacevole sul piano estetico, certo, ma è comunque una possibilità a vostra disposizione, che siete liberi di utilizzare.

Avvertenza: il colore assegnato a una colonna apparirà al di sotto dello sfondo assegnato a una cella. Se dunque avete in programma di assegnare un colore specifico a una cella, sappiate che questo colore avrà il sopravvento sul colore assegnato alla colonna e quella cella apparirà col colore a essa assegnato, invece che col colore della colonna. Dovrebbe essere già ovvio, in base alla regole della ereditarietà, ma è sempre bene specificarlo.

Se decidiamo di assegnare una classe a ogni colonna, qualunque sia il motivo, c’è infine un’altra proprietà che potrebbe interessarci ed è width: con questa possiamo impostare la larghezza di una colonna, esprimendo sempre la dimensione nelle solite unità di misura, che ormai dovrebbero esserci abbastanza familiari. Di conseguenza, se abbiamo creato una classe di stile “colonna”, potremo scrivere la regola
.colonna {
  width: 200px;
}

e assegnare così una larghezza di 200 pixel a quella colonna. Naturalmente poi dovremo assicurarci che la larghezza sia sufficiente per il contenuto della colonna, ma questo è un altro discorso.