Come bloccare la prima riga e la prima colonna in una tabella HTML usando CSS e Javascript / JQuery

how to freeze the first row and the first column of an HTML table
Blog Problem Solving

Questo tutorial spiega come bloccare la prima riga e prima colonna durante lo scorll usando Javascript, JQuery e CSS

Stavo lavorando su una tabella che riporta i permessi di una serie di utenti, la prima riga riporta il tipo di permesso (una ventina circa), la prima colonna riporta il nome degli utenti coinvolti. Ho notato che quando scrollavo la tabella a destra non riuscivo piu’ a vedere a che nome si riferiva la colonna che vedevo, e scollando la tabella in basso perdevo la visione dei permessi.

Ho avuto la necessita’ di creare una tabella con la prima riga e la prima colonna bloccata, in modo da vedere sempre il nome degli utenti e i nome dei permessi.

Bloccare la prima riga o header di una tabella HTML in CSS.

Bloccare la prima riga di una tabella HTML e’ abbastanza facile, per farlo e’ necessario essere sicuri di aver usato i tags  <thead> e <tbody> all’interno del HTML per fare distinzione tra testa l’intestazione della tabella e i valori della tabella stessa. In questo modo possiamo creare uno scroll di tutti i dati bloccando l’intestazione. Ecco un esempio di tabella HTML:

<table>
    <thead>
      <tr>
        <th>&nbsp;</th>
        <th>Jan</th>
        <th>Feb</th>
        <th>Mar</th>
        <th>Apr</th>
        <th>May</th>
        <th>Jun</th>
        <th>Jul</th>
        <th>Aug</th>
        <th>Sep</th>
        <th>Oct</th>
        <th>Nov</th>
        <th>Dec</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <th>1st</th><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
        <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
        <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
      </tr>
    </tbody>
</table>

In questo caso basta bloccare l’altezza di <tbody> in CSS invece di quella di <table> in oltre dobbiamo modificare il CSS di  <tbody> per visualizzare il corpo della tabella in blocco con <display: block>. La proprieta’ < overflow: auto > ci serve a visualizzare la scrollbar.  Sfortunatamente con questa scelta perdiamo la possibilita’ di creare una tabella responsive e adattabile a ogni tipo di schermo. Il problema di questa soluzione e’ che creeremo un grosso spazio tra la tabella e il resto della finestra del browser. Per risolvere questo problema dobbiamo essere sicuri che la grandezza di ogni cella sara’ esattamente la stessa, e la grandezza delle celle dell’intestazione deve coincidere con la grandezza delle celle, altrimenti la tabella sfasera’ l’intestazione con i valori della tabella stessa.
Ecco il CSS di questa soluzione:

table {
    display: block;
    width: 50em;
    max-width: 100%;
    position: relative;
    overflow-x: auto;
}
/* blocco l'altezza del corpo della tabella e visualizzo la scrollbar */
tbody {
    height: 200px;
    overflow: auto;
    display: block;
}
/* fisso la grandezza di ogni cella */ 
th, td {
    width: 3.5em;
}

Bloccare la prima riga di una tabella HTML in JQuery.

Adesso che abbiamo capito come bloccare una parte della tabella e creare lo scrolling dobbiamo cercare di bloccare dinamicamente ogni parte della tabella, o meglio ogni parte che ci interessa bloccare. Sfortunatamente questo approccio in CSS puo’ essere applicato o a sole righe o a sole colonne, non ad entrambe allo stesso tempo.
NOTA: se volete bloccare una riga della tabella HTML dovete sovrascrivere il codice CSS sopra con quello riportato sotto perche’ potrebbe creare un contrasto con il codice jQuery.

Quello che voglio fare e’ “imbrogliare” il CSS e creare una funzione in JQuery che simula il blocco della colonna e crea lo scrolling. Per fare questo usero’ le funzioni scrollTopscrollLeft che restituiscono i numeri di pixel dello scroll. Per maggiori informationi guarda la ducumentazione su questa pagina.

Prima di tutto, diamo un ID alla mia tabella per identificarla quando usero’ JQuery, per esempio <table id="fixed-headers">. Poi devo assocciare la tabella con l’evento scroll del Javascript in modo da eseguire le sucessive funzioni solo in caso di scroll. Ora creo una funzione che trasporta l’intestazione in alto in funzione dei numero di pixel secondo l’asse Y (sostanzialmente, dobbiamo spostare l’header in alto e in basso durante lo scroll). Ecco il codice JQuery:

$('thead').css('transform', 'translateY(' + this.scrollTop + 'px)');

Ora creo una funzione che trasporta la prima colonna della tabella in funzione dei numero di pixel dello scroll secondo l’asse X, sposto quindi la prima colonna a destra e a sinistra. Ecco il codice JQuery:

$('tbody th').css('transform', 'translateX(' + this.scrollLeft + 'px)');

Ora assemblo tutto. Ecco il CSS della tabella:

/* diamo una forma alla tablella HTML */
table {
    display: block;
    width: 50em;
    max-width: 100%;
    position: relative;
}
/* questo attiva la scrollbar */
#fixed-headers {
  border-collapse: collapse;
  height: 300px; 
  display: block; 
  overflow: auto; 
}
/* forzo le celle ad essere della stessa grandezza*/
#fixed-headers td {
  padding: 0 4em !important; 
  border: 1px solid #eee  !important;
}
#fixed-headers thead {
  transform: translateZ(0);
}
#fixed-headers thead th {
    background: #999;
    text-align: center;
}
#fixed-headers tbody th {
    text-align: right;
    background: #999;
    transform: translateZ(0);
}

Ed ecco il mio codice JQuery:

$(function() {
  $('#fixed-headers').scroll(function(ev) {
    /**
     * Quando la tabella scrolla sposta di posizione la prima riga e la prima colonna
     */
    $('thead th').css('transform', 'translateY(' + this.scrollTop + 'px)');
    $('tbody th').css('transform', 'translateX(' + this.scrollLeft + 'px)');
  });
});

Ecco il risultato finale:

 JanFebMarAprMayJunJulAugSepOctNovDec
1st            
2nd            
3rd            
4th            
5th            
6th            
7th            
8th            
9th            
10th            
11th            
12th            
13th            
14th            
15th            
16th            
17th            
18th            
19th            
20th            
21st            
22nd            
23rd            
24th            
25th            
26th            
27th            
28th            
29th            
30th            
31st            

Di seguito il link su CODEPEN del codice qui sopra:  https://codepen.io/webmarcello8080/pen/NWNpOPZ

5 comments

  1. Adriano ~ Adriano says:

    Buongiorno Sig. Marcello,

    Interessante il suo tutorial, peccato però che lo script non funzioni.
    La tabella scrolla perché è attiva la funzione overflow nel css.
    Scrollando su e giù la riga dei mesi resta ferma ma se scrollò verso sinistra, la colonna dei giorni sparisce.

    Grazie

    • Buongiorno.
      Ho dato un altra occhiata al codice js, sembra che funzioni come dovrebbe così come dimostra la demo alla fine della pagina.
      Provi a ricontrollare i tags html e vedere se coincidono su quelli citati all’interno dello script, probabilmente è quello il problema

  2. Adriano Pierdonà ~ Adriano Pierdonà says:

    Buongiorno,
    Mi dispiace ma credo che lo script non funzioni, la prova che non funziona è che se anche tolgo lo script dalla pagina, la tabella scrolla ugualmente su e giù ma come ripeto se scrollò a sinistra la colonna dei giorni sparisce.
    Proverò a ricontrollare bene.

    • Ciao ancora Adriano, forse il fatto che il tutorial propone 2 diversi approcci (uno per bloccare la prima riga in CSS e il secondo per bloccare riga e colonna in jQuery) puo’ creare confusione, la prima parte del codice CSS non va mischiata con la seconda, ho riscritto parte dell’articolo per capire meglio come utilizzarlo.
      Ho anche creato una demo in CODEPEN che ti consente di giocare e cambiare CSS e jQuery come vuoi, ecco il link:
      https://codepen.io/webmarcello8080/pen/NWNpOPZ
      Grazie per la segnalazione.

      • Adriano ~ Adriano says:

        Ciao Marcello,
        Ti ringrazio per l’interesse, proverò a copiare il codice da codepen
        Grazie
        Ciao

Leave a Reply to Anonymous Cancel reply

You May Like

How to animate HTML elements and slide them in on mouse scroll using CSS and Javascript Today I want to animate a bunch of HTML elements and create an animation that moves them inside the same parent DIV once the elements are in the viewport, so only when the elements are visible to the users. […]

August 29, 2023
Read More...

This tutorial will show you how to change your website cursor to any CSS shape and change the shape on hover on certain HTML elements. I have seen a lot of tutorials online about changing the HTML cursor to an SVG icon or to a PGN icon. In my case, I would like to change […]

October 15, 2022
Read More...
woocommerce-min-max-checkout-plugin

Woocommerce Min Max Checkout is a plugin that extends your Woocommerce e-commerce in order to give you the possibility to set the minimum or maximum checkout amount or in order to set a minimum or maximum order quantity on the cart or checkout pages. With Woocommerce Min Max Checkout you can also set e customizable […]

February 12, 2022
Read More...