In un progetto recente mi è capitato di dover creare alcune tabelle per mostrare un tariffario medico. Quando si rappresentano dati tabulari, il rischio di essere poco chiari è dietro l’angolo, soprattutto se la quantità del testo è consistente: nel saltare da una riga all’altra, l’occhio potrebbe confondersi (se poi il carattere è molto piccolo… disastro!). Alternare il colore di sfondo delle righe può essere banale, ma rappresenta un’ottima soluzione! Esiste però un modo “economico” e veloce per realizzarlo con il CSS?
Questo è l’effetto che voglio ottenere:
| Nome servizio | Prezzo | Minuti |
|---|---|---|
| Servizio 1 | 20 € | 10 |
| Servizio 2 | 40 € | 20 |
| Servizio 3 | 10 € | 5 |
| Servizio 4 | 30 € | 15 |
Ho deciso di affidarmi ad uno strumento che adoro: il forum di CSS-Tricks. E la risposta è arrivata dopo neanche due ore! Mi è stato infatti suggerito (e mostrato) come sfruttare a tal vantaggio la proprietà nth-child. La definizione del W3C dice che tale proprietà serve ad intercettare ogni “ennesimo” elemento figlio (child) di un dato contenitore (parent) a prescindere dal tipo di oggetto in questione. Per esempio, le righe (<tr>) di una tabella si possono proprio considerare “figlie” dell’oggetto che le contiene: la “tabella” (<table>).
Ogni volta che incontro una nuova proprietà CSS, per prima cosa controllo sempre la compatibilità con i vari browsers: in questo caso, scopro che nth-child è largamente supportata. Naturalmente, la pecora nera è sempre Internet Explorer: dalla versione 8 (compresa) verso il basso, possiamo scordarci che venga rispettata. Ne riparlerò più avanti, per ora ecco il codice HTML della mia tabella:
<table>
<tbody>
<tr>
<th>Nome servizio</th>
<th>Prezzo</th>
<th>Minuti</th>
</tr>
<tr>
<td>Servizio 1</td>
<td>20 €</td>
<td>10</td>
</tr>
<tr>
<td>Servizio 2</td>
<td>40 €</td>
<td>20</td>
</tr>
<tr>
<td>Servizio 3</td>
<td>10 €</td>
<td>5</td>
</tr>
<tr>
<td>Servizio 4</td>
<td>30 €</td>
<td>15</td>
</tr>
</tbody>
</table>
Ed ecco la proprietà nth-child in azione:
tr:nth-child(even) {
background-color: grey;
}
Esatto, tutto qui! Ecco spiegato in dettaglio che cosa ho scritto:
tr: è l’oggetto che voglio intercettare (la riga della mia tabella):nth-child: il codice che richiama la proprietà(even): rappresenta il “parametro” (discriminante) di selezione. even significa “pari”, ed infatti ho intercettato e cambiato il colore di sfondo a tutte le righe “pari” della tabellaI più esperti riconosceranno nth-child come quello che in realtà è: una pseudo-classe (le “pseudo classi” si riconoscono sempre dalla presenza dei “:”). E se avessi voluto intercettare solo le righe “dispari”? Semplice: avrei dovuto scrivere odd al posto di even.
nth-child è molto più di questo...Esco per un attimo dall’esempio pratico del tariffario medico, per dire che in realtà la proprietà nth-child può essere usata in modo molto più complesso, fino a far fronte a una larga scala di applicazioni. Ad esempio, se volessi cambiare colore a tutti gli elementi <li> di una lista che sono multipli di 3:
Il CSS diventerrebbe:
li:nth-child(3n + 0) {
color: red;
}
Entrano così in gioco due nuovi elementi: 3n (n è una variabile, mentre 3 il suo coefficiente) e un numero (in questo caso 0) che chiamerò “offset”. Il gioco sta nel risolvere l’equazione 3n + 0, dove a variare è sempre e solo il valore di n (si parte da 0 e si percorrono tutti i numeri interi positivi fino all’infinito). Che spiegazione ostica… Per fortuna che la soluzione è facilissima!
n = 0 => 3n + 0 = 0n = 1 => 3n + 0 = 3n = 2 => 3n + 0 = 6n = 3 => 3n + 0 = 9n = 4 => …In pratica, nth:child ha selezionato gli elementi di indice 3, 6 e 9 (non esiste infatti l’elemento 0, e se la mia lista fosse stata più lunga l’equazione non si sarebbe nemmeno fermata a 9). E adesso ancora più difficile! (4n + 1):
Ovvero:
n = 0 => 4n + 1 = 1n = 1 => 4n + 1 = 5n = 2 => 4n + 1 = 9n = 3 => …Posso anche semplificare al massimo, indicando un solo parametro (4):
C’è bisogno di spiegarlo?
Per finire, si possono anche usare dei numeri negativi, sia sul coefficiente di n (come (-n + 3)), sia davanti al valore di offset (ad esempio (2n - 6)). Qualcuno potrebbe chiedersi che senso avrebbe usare valori negativi… Ed ecco che invece salta fuori essere un trucchetto molto utile! Ad esempio, se voglio selezionare solo i primi 5 elementi di una lista, posso usare (-n + 5). Infatti:
n = 0 => -n + 5 = 5n = 1 => -n + 5 = 4n = 2 => -n + 5 = 3n = 3 => -n + 5 = 2n = 4 => -n + 5 = 1n = 5 => -n + 5 = 0 (nulla)Se hai ancora dubbi sul funzionamento della proprietà nth-child o semplicemente vuoi testare il risultato prima di applicarlo in un caso reale, CSS-Tricks offre un comodo tool fatto apposta per questo scopo.
Nel caso fossi obbligato a supportare anche i browser più “capricciosi”, puoi sfruttare ad esempio la libreria Javascript Selectivizr, che è stata scritta apposta per emulare i più recenti selettori anche in versioni obsolete di Internet Explorer: la 6, la 7 e 8. Non spiego qui come utilizzare la libreria (è spiegata benissimo anche sul sito ufficiale), ma magari in futuro ne farò un tutorial…