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

You May Like

Today we try to analyze the error that appears on the browser inspector and that is a bit tricky to fix and we try to understand what is causing the error, the error is called “Failed to load resource: net::ERR_BLOCKED_BY_CLIENT“. This error is always followed by an URL, this URL is the link that has […]

May 28, 2021
Read More...
how to freeze the first row and the first column of an HTML table

I was working on an HTML table that displays a list of users and user permission, the first row displays the permission names and the first column displays the name of the users involved. I have noticed that when I strolled toward the right I couldn’t see the user names and scrolling toward the bottom […]

May 28, 2021
Read More...

The Fullscreen Any Element Plugin uses the Javascript Fullscreen API in order to make any chosen HTML element on your website in fullscreen. The Fullscreen API adds methods to present a specific Element (and its descendants) in full-screen mode, and to exit full-screen mode once it is no longer needed. This makes it possible to […]

May 24, 2021
Read More...

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

Click to Leave a Comment