Tabelle responsive con CSS3

Tabella responsive con css3
Tabella responsive con css3

L'uso sempre più frequente degli smartphone per accedere al web, ha introdotto il problema, tra le altre cose, di visualizzare elementi di grandi dimensioni che a video non hanno nessuna difficoltà ma che, appunto, su tipi di media diversi dal monitor del pc, risultano completamente rovinati o peggio ancora, inducono ad un frequente e snervante scroll orizzontale e verticale. Tra questi elementi annotiamo le tabelle. L'argomento di oggi tratta come realizzare una tabella completamente responsive con i CSS3.

La screenshot seguente mostra come dovrebbe essere visualizzato il contenuto di una tabella, attraverso uno smartphone. E' la stessa tabella mostrata nella intro dell'articolo. Nulla è stato eliminato per renderla adattabile, bensì è stato scritto codice CSS3 per fare in modo che nulla vada perduto.

Tabella responsive per smartphone
Tabella Responsive su smartphone

Il codice html

Il codice html non presenta nulla di diverso dalla canonica realizzazione di tabelle classiche. Qualche rigo di codice aiuta a capire meglio:

<table class="responsive">

<thead>
	<tr >
        <th>HEAD 1</th>
        <th>HEAD 2</th>
        <th>HEAD 3</th>
	</tr >	
</thead>

<tbody>
   <tr>
	<td>Cella 1</td>
        <td>Cella 1</td>
        <td>Cella 1</td> 
   </tr>
...................

</tbody>

</table>

Il codice CSS

Il codice CSS prevede, a solo scopo dimostrativo, un solo break-point. Vale a dire che se visualizziamo la pagina su un media con viewport fino a 799px, avremo la tabella come quella visualizzata attraverso l'Iphone. Se, invece, si vede la stessa pagina con dimensione a partire da 800px, allora verrà visualizzata la tabella come l'immagine iniziale della pagina.

Ovviamente, le dimensioni della tabella dovrebbero essere studiate in base ai contenuti. Quanto testo si ha in ogni singola cella ecc... Per l'esempio in oggetto, ho stabilito un solo break-point. Partiamo dal codice CSS per schermi da 800px in su (desktop):

.responsive {
border-collapse:collapse;
border-spacing:0;
margin:0 auto 40px;
}

@media screen and (min-width:800px){

.responsive {width: 80%;}

.responsive thead th {
height:50px;
line-height:50px;
border:1px solid #ddd;
background: navy;
color:#fff;
}

.responsive tbody td {
height:40px;
line-height:40px;
border:1px solid #ddd;
}
}

@media screen and (max-width:799px) {
.responsive, thead, tbody, th, tr, td {display: block;}

.responsive {width:90%;}
}

Per media a partire da 800px in poi, il codice è davvero molto semplice. Non c'è alcun rigo che vada commentato. Per quanto riguarda, invece, il codice per schermi di dimensioni inferiori - @media screen and (max-width:799px) - le cose cominciano a cambiare un po'.

Tutti gli elementi della tabella devono essere dichiarati display: block. Vale a dire che devono essere posizionati uno sotto l'altro. Si veda sempre la screenshot della tabella attraverso lo smartphone.

Eliminare gli elementi con position: absolute

Nella screenshot dell'Iphone, non appaiono le intestazioni th perchè esse saranno "traslate" a sinistra della tabella, e non più in alto. Inoltre saranno sostituite da elementi td. Andiamo con ordine:

.responsive thead tr th {
position: absolute;
top: -9999px;
left: -9999px;
}

E' importante usare la proprietà position: absolute perchè, se è vero che le intestazioni di tabella non devono essere visualizzate in uno smartphone, devono "mantenere" la loro posizione per l'accessibilità. Se avessi scritto display: none avrei reso di difficile comprensione la struttura della tabella per chi "legge" la pagina con uno screen-reader.

Vediamo adesso la parte più importante. Quello che si farà, sarà forzare la tabella a non avere l'impostazione classica, ma a rendere ogni suo elemento come elemento di blocco. Le celle non verranno più "costruite" orizzontalmente, bensì verticalmente. Disposte una sull'altra, appunto. In questo modo non ci sarà più la barra di scroll orizzontale per visualizzare tutte i contenuti delle celle. In ultimo, per ogni cella si utilizzerà il contenuto generato :before che fungerà da "etichetta" in maniera tale da associare tale etichetta al contenuto di ogni riga di tabella.

@media screen and (max-width:799px) {

.responsive td:before {
position: absolute;
top: 0;
left: 5px;
padding-right: 0;
white-space: nowrap;
width:100%;
}

.responsive tbody td {
border: none;
border-bottom: 1px solid #ddd;
position: relative;
text-align: left;
height:30px;
line-height:30px;
padding-left: 70%;
}

.responsive td:nth-of-type(1):before { content: "HEAD 1"; }
.responsive td:nth-of-type(2):before { content: "HEAD 2"; }
.responsive td:nth-of-type(3):before { content: "HEAD 3"; }
}

Se volessimo assegnare un colore alternato per ogni riga di tabella, possiamo farlo attraverso il seguente codice CSS:

.responsive tr:nth-of-type(odd) { 
background:#f5f5f5; 
}

La oggetto dell'articolo. A seconda delle dimensioni della finestra del browser, si passerà dalla tabella "classica" a quella per smarphone, tablet ecc.