Tabella HTML con larghezza del 100%, con scorrimento verticale all'interno del corpo


423

Come posso impostare una <table>larghezza del 100% e inserirla solo all'interno dello <tbody>scorrimento verticale per una certa altezza?

scorrimento verticale all'interno del corpo

table {
    width: 100%;
    display:block;
}
thead {
    display: inline-block;
    width: 100%;
    height: 20px;
}
tbody {
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}
  
<table>
  <thead>
    <tr>
    	<th>Head 1</th>
    	<th>Head 2</th>
    	<th>Head 3</th>
    	<th>Head 4</th>
    	<th>Head 5</th>
    </tr>
  </thead>
  <tbody>
    <tr>
    	<td>Content 1</td>
    	<td>Content 2</td>
    	<td>Content 3</td>
    	<td>Content 4</td>
    	<td>Content 5</td>
    </tr>
  </tbody>
</table>

Voglio evitare di aggiungere alcuni div aggiuntivi, tutto ciò che voglio è una tabella semplice come questa e quando provo a cambiare la visualizzazione table-layout, positione molte altre cose nella tabella CSS non funzionano bene con una larghezza del 100% solo con una larghezza fissa in px.


non sono davvero sicuro di ciò che vuoi ottenere. guarda questo: jsfiddle.net/CrSpu e dì come vuoi che si comporti
x4rf41

2
lo so ma guarda .. th e td non sono mostrati a tutta larghezza .. postimg.org/image/mgd630y61
Marko S


Risposte:


675

Al fine di rendere <tbody>scorrevole l'elemento, dobbiamo cambiare il modo in cui viene visualizzato sulla pagina, ad esempio usando display: block;per visualizzarlo come elemento a livello di blocco.

Dato che cambiamo la displayproprietà di tbody, dovremmo cambiare anche quella proprietà per theadelement per evitare di rompere il layout della tabella.

Quindi abbiamo:

thead, tbody { display: block; }

tbody {
    height: 100px;       /* Just for the demo          */
    overflow-y: auto;    /* Trigger vertical scroll    */
    overflow-x: hidden;  /* Hide the horizontal scroll */
}

I browser Web visualizzano gli elementi theade tbodycome gruppo di righe ( table-header-groupe table-row-group) per impostazione predefinita.

Una volta che lo cambiamo, gli trelementi interni non riempiono l'intero spazio del loro contenitore.

Per risolvere questo problema, dobbiamo calcolare la larghezza delle tbodycolonne e applicare il valore corrispondente athead colonne tramite JavaScript.

Colonne di larghezza automatica

Ecco la versione jQuery della logica sopra:

// Change the selector if needed
var $table = $('table'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

// Get the tbody columns width array
colWidth = $bodyCells.map(function() {
    return $(this).width();
}).get();

// Set the width of thead columns
$table.find('thead tr').children().each(function(i, v) {
    $(v).width(colWidth[i]);
});    

Ed ecco l'output (su Windows 7 Chrome 32) :

scorrimento verticale all'interno del corpo

DEMO DI LAVORO .

Tabella a larghezza piena, colonne a larghezza relativa

In base alle necessità del poster originale, è possibile espandere il table100% del widthsuo contenitore e quindi utilizzare un relativo ( percentuale ) widthper ogni colonna della tabella.

table {
    width: 100%; /* Optional */
}

tbody td, thead th {
    width: 20%;  /* Optional */
}

Poiché la tabella ha una ( fluida ) disposizione del layout , dovremmo regolare la larghezza delle theadcolonne quando il contenitore viene ridimensionato.

Quindi dovremmo impostare le larghezze delle colonne una volta ridimensionata la finestra:

// Adjust the width of thead cells when *window* resizes
$(window).resize(function() {
    /* Same as before */ 
}).resize(); // Trigger the resize handler once the script runs

L'output sarebbe:

Tavolo fluido con scorrimento verticale all'interno del corpo

DEMO DI LAVORO .


Supporto browser e alternative

Ho testato i due metodi sopra su Windows 7 tramite le nuove versioni dei principali browser Web (incluso IE10 +) e ha funzionato.

Tuttavia, non funziona correttamente su IE9 e versioni precedenti .

Questo perché in un layout di tabella , tutti gli elementi dovrebbero seguire le stesse proprietà strutturali.

Usando display: block;per gli elementi <thead>e <tbody>, abbiamo rotto la struttura della tabella.

Riprogettare il layout tramite JavaScript

Un approccio consiste nel ridisegnare il layout (intero) della tabella. Utilizzando JavaScript per creare un nuovo layout al volo e gestire e / o regolare le larghezze / altezze delle celle in modo dinamico.

Ad esempio, dai un'occhiata ai seguenti esempi:

Tavoli a incastro

Questo approccio utilizza due tabelle nidificate con un div contenente. Il primo tableha solo una cella che ha un div, e la seconda tabella è posizionata all'interno di divquell'elemento.

Controlla le tabelle di scorrimento verticale su CSS Play .

Funziona sulla maggior parte dei browser Web. Possiamo anche fare la logica di cui sopra dinamicamente tramite JavaScript.

Tabella con intestazione fissa su scroll

Poiché lo scopo dell'aggiunta della barra di scorrimento verticale alla <tbody>visualizzazione dell'intestazione della tabella nella parte superiore di ogni riga, è possibile posizionare l' theadelemento in modo che rimangafixed nella parte superiore dello schermo.

Ecco una demo funzionante di questo approccio eseguito da Julien .
Ha un promettente supporto per browser web.

E qui una pura implementazione CSS di Willem Van Bockstal .


La soluzione CSS pura

Ecco la vecchia risposta. Naturalmente ho aggiunto un nuovo metodo e perfezionato le dichiarazioni CSS.

Tavolo con larghezza fissa

In questo caso, tabledovrebbe avere un valore fisso width (inclusa la somma delle larghezze delle colonne e la larghezza della barra di scorrimento verticale) .

Ogni colonna deve avere una determinata larghezza e l' ultima colonna di theadelemento ha bisogno di una maggiore larghezza pari ad altrui larghezza + la larghezza della barra di scorrimento verticale.

Pertanto, il CSS sarebbe:

table {
    width: 716px; /* 140px * 5 column + 16px scrollbar width */
    border-spacing: 0;
}

tbody, thead tr { display: block; }

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 140px;
}

thead th:last-child {
    width: 156px; /* 140px + 16px scrollbar width */
}

Ecco l'output:

Tavolo con larghezza fissa

DEMO DI LAVORO .

Tavolo con larghezza 100%

In questo approccio, tableha una larghezza di 100%e per ciascuno the td, il valore della widthproprietà dovrebbe essere inferiore a 100% / number of cols.

Inoltre, dobbiamo ridurre la larghezza di theadcome valore della larghezza della barra di scorrimento verticale.

Per fare ciò, dobbiamo usare la calc()funzione CSS3 , come segue:

table {
    width: 100%;
    border-spacing: 0;
}

thead, tbody, tr, th, td { display: block; }

thead tr {
    /* fallback */
    width: 97%;
    /* minus scroll bar width */
    width: -webkit-calc(100% - 16px);
    width:    -moz-calc(100% - 16px);
    width:         calc(100% - 16px);
}

tr:after {  /* clearing float */
    content: ' ';
    display: block;
    visibility: hidden;
    clear: both;
}

tbody {
    height: 100px;
    overflow-y: auto;
    overflow-x: hidden;
}

tbody td, thead th {
    width: 19%;  /* 19% is less than (100% / 5 cols) = 20% */
    float: left;
}

Ecco la demo online .

Nota: questo approccio fallirà se il contenuto di ogni colonna interrompe la linea, ovvero il contenuto di ogni cella dovrebbe essere abbastanza breve .


Di seguito, ci sono due semplici esempi di soluzione CSS pura che ho creato nel momento in cui ho risposto a questa domanda.

Ecco la jsFiddle Demo v2 .

Vecchia versione: jsFiddle Demo v1


17
Con display: blockte perdi le proprietà della tabella come larghezza della colonna condivisa tra la testa e il corpo. So che l'hai risolto impostando, width: 19.2%ma nel caso in cui non conosciamo in anticipo la larghezza di ogni colonna, questo non funzionerà.
Samb

10
Questo codice sembra presupporre che le cellule del corpo saranno sempre più larghe delle celle dell'intestazione.
Adam Donahue,

2
Non funziona quando height: 100%(quando si desidera che la tabella si espanda fino alla fine della pagina).
AlikElzin-Kilaka,

2
Questo funziona anche in modo fantastico con le ng-repeattabelle AngularJS . Non so perché ci siano tutte quelle librerie con intestazioni di tabella fisse e cosa no quando c'è questa soluzione.
Chakeda,

2
Puoi migliorarlo un po 'di più con la box-sizingproprietà in modo che i bordi di due spessori diversi non eliminino l'allineamento della colonna.
Ricca,

89

Nella seguente soluzione, la tabella occupa il 100% del contenitore padre, non sono richieste dimensioni assolute. È puro CSS, viene utilizzato il layout flessibile.

Ecco come appare: inserisci qui la descrizione dell'immagine

Possibili svantaggi:

  • la barra di scorrimento verticale è sempre visibile, indipendentemente dal fatto che sia richiesta;
  • il layout della tabella è fisso - le colonne non vengono ridimensionate in base alla larghezza del contenuto (è comunque possibile impostare la larghezza della colonna desiderata in modo esplicito);
  • c'è una dimensione assoluta - la larghezza della barra di scorrimento, che è di circa 0,9em per i browser che sono stato in grado di controllare.

HTML (abbreviato):

<div class="table-container">
    <table>
        <thead>
            <tr>
                <th>head1</th>
                <th>head2</th>
                <th>head3</th>
                <th>head4</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            <tr>
                <td>content1</td>
                <td>content2</td>
                <td>content3</td>
                <td>content4</td>
            </tr>
            ...
        </tbody>
    </table>
</div>

CSS, con alcune decorazioni omesse per chiarezza:

.table-container {
    height: 10em;
}
table {
    display: flex;
    flex-flow: column;
    height: 100%;
    width: 100%;
}
table thead {
    /* head takes the height it requires, 
    and it's not scaled when table is resized */
    flex: 0 0 auto;
    width: calc(100% - 0.9em);
}
table tbody {
    /* body takes all the remaining available space */
    flex: 1 1 auto;
    display: block;
    overflow-y: scroll;
}
table tbody tr {
    width: 100%;
}
table thead, table tbody tr {
    display: table;
    table-layout: fixed;
}

codice completo su jsfiddle

Stesso codice in MENO in modo da poterlo mescolare in:

.table-scrollable() {
  @scrollbar-width: 0.9em;
  display: flex;
  flex-flow: column;

  thead,
  tbody tr {
    display: table;
    table-layout: fixed;
  }

  thead {
    flex: 0 0 auto;
    width: ~"calc(100% - @{scrollbar-width})";
  }

  tbody {
    display: block;
    flex: 1 1 auto;
    overflow-y: scroll;

    tr {
      width: 100%;
    }
  }
}

2
Grazie per la soluzione! Si è verificato un leggero errore ... hai impostato due volte la larghezza per il tallone e ho scoperto che sottraendo 1.05em dalla larghezza si allinea un po 'meglio: jsfiddle.net/xuvsncr2/170
TigerBear

1
che dire del numero di contenuti del personaggio? si incasina quando si aggiungono più caratteri o parole all'interno delle celle de row
Limon

Penso che impostare una politica di avvolgimento adeguata tddovrebbe aiutare
tsayen

Qualche soluzione come questa ma fa cadere la necessità della larghezza del 100%?
Alexandre Pereira Nunes,

2
@tsayen Come si impedisce che si scricchioli e si sovrapponga quando si ridimensiona la finestra?
clearshot66

31

Nei browser moderni, puoi semplicemente usare css:

th {
  position: sticky;
  top: 0;
  z-index: 2;
}

8
Questo incantesimo è incompleto ... Ti interessa pubblicare un esempio, o almeno elaborato?
Liam,

funziona bene, ma si applica solo a th. Se impostiamo la posizione appiccicosa sulla testa, allora non funziona.
Vishal,

Il thead fisso dovrebbe aggiungere al W3C!
Sonichy,

2
Questa risposta funziona quando avvolgi il tuo <table>con ciò <div>che ha overflow-y: auto;e alcuni max-height. Ad esempio:<div style="overflow-y: auto; max-height: 400px;"><table>...</table></div>
Minwork

A partire dal 2020, questa sarà la risposta selezionata (insieme all'aggiornamento di @Minwork)
Christophe Vidal

18

Sto usando display:blockper theade tbody. Per questo motivo la larghezza delle theadcolonne è diversa dalla larghezza delle tbodycolonne.

table {
    margin:0 auto; 
    border-collapse:collapse;
}
thead {
    background:#CCCCCC;
    display:block
}
tbody {
    height:10em;overflow-y:scroll;
    display:block
}

Per risolvere questo problema, utilizzo un jQuerycodice piccolo ma può essere eseguito JavaScriptsolo in.

var colNumber=3 //number of table columns    

for (var i=0; i<colNumber; i++) {
  var thWidth=$("#myTable").find("th:eq("+i+")").width();
  var tdWidth=$("#myTable").find("td:eq("+i+")").width();      
  if (thWidth<tdWidth)                    
      $("#myTable").find("th:eq("+i+")").width(tdWidth);
  else
      $("#myTable").find("td:eq("+i+")").width(thWidth);           
}  

Ecco la mia demo di lavoro: http://jsfiddle.net/gavroche/N7LEF/

Non funziona in IE 8


Questa è la soluzione migliore / più semplice che ho trovato che consente larghezze di colonna non fisse (ad es. Controllo .NET DataGrid). Per "produzione", la colNumbervariabile potrebbe essere sostituita dal codice che scorre invece attraverso le celle effettive trovate, e nota che non riesce a far fronte correttamente se ci sono colspans (potrebbe anche essere migliorato nel codice, se necessario, ma improbabile sul tipo di tabella che probabilmente vorrà questa funzione di scorrimento).
JonBrave,

Funziona (in un modo), ma non fa fronte quando la dimensione della finestra è inferiore alla tabella (poiché ignora la larghezza della barra di scorrimento).
Codice finito il

Sì, l'intestazione e le celle non corrispondono più se la larghezza della tabella è limitata a una larghezza impostata
Craig,

la migliore risposta qui, anche la più semplice
Charles Okwuagwu il

18

CSS-only

per Chrome, Firefox, Edge (e altri browser sempreverdi )

Semplicemente i position: sticky; top: 0;tuoi thelementi:

/* Fix table head */
.tableFixHead    { overflow-y: auto; height: 100px; }
.tableFixHead th { position: sticky; top: 0; }

/* Just common table stuff. */
table  { border-collapse: collapse; width: 100%; }
th, td { padding: 8px 16px; }
th     { background:#eee; }
<div class="tableFixHead">
  <table>
    <thead>
      <tr><th>TH 1</th><th>TH 2</th></tr>
    </thead>
    <tbody>
      <tr><td>A1</td><td>A2</td></tr>
      <tr><td>B1</td><td>B2</td></tr>
      <tr><td>C1</td><td>C2</td></tr>
      <tr><td>D1</td><td>D2</td></tr>
      <tr><td>E1</td><td>E2</td></tr>
    </tbody>
  </table>
</div>

PS: se hai bisogno di bordi per gli elementi TH th {box-shadow: 1px 1px 0 #000; border-top: 0;}ti aiuterà (poiché i bordi predefiniti non sono dipinti correttamente sulla pergamena).

Per una variante di quanto sopra che utilizza solo un po 'di JS per adattarsi a IE11, consultare questa risposta https://stackoverflow.com/a/47923622/383904


Se hai bordi per questi elementi, usando "border-collapse: collapse" il bordo verrà incollato sul corpo anziché sull'intestazione. Per evitare questo problema dovresti usare "border-collapse: separate". Vedere stackoverflow.com/a/53559396
mrod

@mrod quando usi separateaggiungi olio al fuoco. jsfiddle.net/RokoCB/o0zL4xyw e vedere una soluzione QUI: aggiungi i bordi al TH fisso - Sono il benvenuto per i suggerimenti OFC se ho perso qualcosa.
Roko C. Buljan,

11

Crea due tabelle una dopo l'altra, metti la seconda tabella in un div di altezza fissa e imposta la proprietà di overflow su auto. Inoltre, mantieni vuoti tutti gli oggetti all'interno del thd nella seconda tabella.

<div>
    <table>
        <thead>
            <tr>
                <th>Head 1</th>
                <th>Head 2</th>
                <th>Head 3</th>
                <th>Head 4</th>
                <th>Head 5</th>
            </tr>
        </thead>
    </table>
</div>

<div style="max-height:500px;overflow:auto;">
    <table>
        <thead>
            <tr>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
        <tr>
            <td>Content 1</td>
            <td>Content 2</td>
            <td>Content 3</td>
            <td>Content 4</td>
            <td>Content 5</td>
        </tr>
        </tbody>
    </table>    
</div>

8
In questo caso, le colonne della seconda tabella non possono seguire la larghezza della prima tabella.
Kat 1330,

2
Non bene! Si perde la sincronizzazione della larghezza per le colonne su due tabelle.
Zafar,

1
per completare questa soluzione è necessario aggiungere lo script @Hashem Qolami ( descritto sopra ) per sincronizzare la larghezza delle colonne di intestazione
Elhay Avichzer

6

Ho finalmente capito bene con CSS puro seguendo queste istruzioni:

http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/

Il primo passo è impostare il <tbody>display: block in modo da poter applicare un overflow e un'altezza. Da lì le righe <thead>devono essere impostate su position: relative e display: block in modo che si siedano in cima all'ora scorrevole <tbody>.

tbody, thead { display: block; overflow-y: auto; }

Poiché <thead>è relativamente posizionata, ogni cella della tabella necessita di una larghezza esplicita

td:nth-child(1), th:nth-child(1) { width: 100px; }
td:nth-child(2), th:nth-child(2) { width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Ma sfortunatamente non è abbastanza. Quando è presente una barra di scorrimento, i browser allocano lo spazio per essa, quindi, <tbody>finisce per avere meno spazio disponibile rispetto a <thead>. Notare il leggero disallineamento che questo crea ...

L'unica soluzione che mi è venuta in mente è stata quella di impostare una larghezza minima su tutte le colonne tranne l'ultima.

td:nth-child(1), th:nth-child(1) { min-width: 100px; }
td:nth-child(2), th:nth-child(2) { min-width: 100px; }
td:nth-child(3), th:nth-child(3) { width: 100px; }

Esempio di codice intero di seguito:

CSS:

.fixed_headers {
  width: 750px;
  table-layout: fixed;
  border-collapse: collapse;
}
.fixed_headers th {
  text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
  padding: 5px;
  text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
  min-width: 200px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
  min-width: 200px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
  width: 350px;
}
.fixed_headers thead {
  background-color: #333333;
  color: #fdfdfd;
}
.fixed_headers thead tr {
  display: block;
  position: relative;
}
.fixed_headers tbody {
  display: block;
  overflow: auto;
  width: 100%;
  height: 300px;
}
.fixed_headers tbody tr:nth-child(even) {
  background-color: #dddddd;
}
.old_ie_wrapper {
  height: 300px;
  width: 750px;
  overflow-x: hidden;
  overflow-y: auto;
}
.old_ie_wrapper tbody {
  height: auto;
}

html:

<!-- IE < 10 does not like giving a tbody a height.  The workaround here applies the scrolling to a wrapped <div>. -->
<!--[if lte IE 9]>
<div class="old_ie_wrapper">
<!--<![endif]-->

<table class="fixed_headers">
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Plum</td>
      <td>Purple</td>
      <td>These are Purple</td>
    </tr>
    <tr>
      <td>Watermelon</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Tomato</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cherry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Cantelope</td>
      <td>Orange</td>
      <td>These are orange inside.</td>
    </tr>
    <tr>
      <td>Honeydew</td>
      <td>Green</td>
      <td>These are green inside.</td>
    </tr>
    <tr>
      <td>Papaya</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Raspberry</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Blueberry</td>
      <td>Blue</td>
      <td>These are blue.</td>
    </tr>
    <tr>
      <td>Mango</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Passion Fruit</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

<!--[if lte IE 9]>
</div>
<!--<![endif]-->

EDIT: soluzione alternativa per la larghezza della tabella al 100% (sopra in realtà è per la larghezza fissa e non ha risposto alla domanda):

HTML:

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Color</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
      <td>These are red.</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
    <tr>
      <td>Grape</td>
      <td>Purple / Green</td>
      <td>These are purple and green.</td>
    </tr>
    <tr>
      <td>Orange</td>
      <td>Orange</td>
      <td>These are orange.</td>
    </tr>
    <tr>
      <td>Banana</td>
      <td>Yellow</td>
      <td>These are yellow.</td>
    </tr>
    <tr>
      <td>Kiwi</td>
      <td>Green</td>
      <td>These are green.</td>
    </tr>
  </tbody>
</table>

CSS:

table {
  width: 100%;
  text-align: left;
  min-width: 610px;
}
tr {
  height: 30px;
  padding-top: 10px
}
tbody { 
  height: 150px; 
  overflow-y: auto;
  overflow-x: hidden;
}
th,td,tr,thead,tbody { display: block; }
td,th { float: left; }
td:nth-child(1),
th:nth-child(1) {
  width: 20%;
}
td:nth-child(2),
th:nth-child(2) {
  width: 20%;
  float: left;
}
td:nth-child(3),
th:nth-child(3) {
  width: 59%;
  float: left;
}
/* some colors */
thead {
  background-color: #333333;
  color: #fdfdfd;
}
table tbody tr:nth-child(even) {
  background-color: #dddddd;
}

Demo: http://codepen.io/anon/pen/bNJeLO


1
La domanda voleva specificamente una tabella di larghezza del 100%, che è l'unica cosa che l'esempio a cui hai fatto riferimento non fa.
Codice finito il

@TrueBlueAussie Buona cattura: D Aggiunta soluzione alternativa per una larghezza del 100%.
Mikael Lepistö,

non consideri la longitudine del contenuto della riga della cella
Limon

2

Soluzione CSS per forzare la visualizzazione corretta delle colonne con un corpo a "blocco"

Questa soluzione richiede ancora che le thlarghezze vengano calcolate e impostate da jQuery

table.scroll tbody,
table.scroll thead { display: block; }

table.scroll tbody {
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 300px;
}

table.scroll tr {
    display: flex;
}

table.scroll tr > td {
    flex-grow: 1;
    flex-basis: 0;
}

E il Jquery / Javascript

var $table = $('#the_table_element'),
    $bodyCells = $table.find('tbody tr:first').children(),
    colWidth;

$table.addClass('scroll');

// Adjust the width of thead cells when window resizes
$(window).resize(function () {

    // Get the tbody columns width array
    colWidth = $bodyCells.map(function () {
        return $(this).width();
    }).get();

    // Set the width of thead columns
    $table.find('thead tr').children().each(function (i, v) {
        $(v).width(colWidth[i]);
    });

}).resize(); // Trigger resize handler

@Craig nel 2019, va benissimo non preoccuparsi di IE.
Automagisch,

2

prova l'approccio sotto, molto semplice, facile da implementare

Di seguito è riportato il link jsfiddle

http://jsfiddle.net/v2t2k8ke/2/

HTML:

<table border='1' id='tbl_cnt'>
<thead><tr></tr></thead><tbody></tbody>

CSS:

 #tbl_cnt{
 border-collapse: collapse; width: 100%;word-break:break-all;
 }
 #tbl_cnt thead, #tbl_cnt tbody{
 display: block;
 }
 #tbl_cnt thead tr{
 background-color: #8C8787; text-align: center;width:100%;display:block;
 }
 #tbl_cnt tbody {
 height: 100px;overflow-y: auto;overflow-x: hidden;
 }

jquery:

 var data = [
    {
    "status":"moving","vehno":"tr544","loc":"bng","dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che", "dri":"ttt"
    },{    "status":"idle","vehno":"yy5499999999999994","loc":"bng","dri":"ttt"
    },{
    "status":"moving","vehno":"tr544","loc":"bng", "dri":"ttt"
    }, {
    "status":"stop","vehno":"tr54","loc":"che","dri":"ttt"
    },{
    "status":"idle","vehno":"yy544","loc":"bng","dri":"ttt"
    }
    ];
   var sth = '';
   $.each(data[0], function (key, value) {
     sth += '<td>' + key + '</td>';
   });
   var stb = '';        
   $.each(data, function (key, value) {
       stb += '<tr>';
       $.each(value, function (key, value) {
       stb += '<td>' + value + '</td>';
       });
       stb += '</tr>';
    });
      $('#tbl_cnt thead tr').append(sth);
      $('#tbl_cnt tbody').append(stb);
      setTimeout(function () {
      var col_cnt=0 
      $.each(data[0], function (key, value) {col_cnt++;});    
      $('#tbl_cnt thead tr').css('width', ($("#tbl_cnt tbody") [0].scrollWidth)+ 'px');
      $('#tbl_cnt thead tr td,#tbl_cnt tbody tr td').css('width',  ($('#tbl_cnt thead tr ').width()/Number(col_cnt)) + 'px');}, 100)

2
Questa soluzione non affronta la finestra essendo più stretta della larghezza della tabella. Dovrebbe consentire lo scorrimento orizzontale quando ciò accade. Inoltre, le intestazioni non si allineano esattamente con le celle di dati (Chrome).
Codice finito il

Non funziona al giorno d'oggi
MrHIDEn,

2

Aggiungendo una larghezza fissa a td, th dopo aver realizzato il blocco display tbody e thead funziona perfettamente e anche noi possiamo usare il plugin slimscroll per rendere bella la barra di scorrimento.

inserisci qui la descrizione dell'immagine

<!DOCTYPE html>
<html>

<head>
    <title> Scrollable table </title>
    <style>
        body {
            font-family: sans-serif;
            font-size: 0.9em;
        }
        table {
            border-collapse: collapse;
            border-bottom: 1px solid #ddd;
        }
        thead {
            background-color: #333;
            color: #fff;
        }
        thead,tbody {
            display: block;
        }
        th,td {
            padding: 8px 10px;
            border: 1px solid #ddd;
            width: 117px;
            box-sizing: border-box;
        }
        tbody {
            height: 160px;
            overflow-y: scroll
        }
    </style>
</head>

<body>

    <table class="example-table">
        <thead>
            <tr>
                <th> Header 1 </th>
                <th> Header 2 </th>
                <th> Header 3 </th>
                <th> Header 4 </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td> Row 1- Col 1 </td>
                <td> Row 1- Col 2 </td>
                <td> Row 1- Col 3 </td>
                <td> Row 1- Col 4 </td>
            </tr>
            <tr>
                <td> Row 2- Col 1 </td>
                <td> Row 2- Col 2 </td>
                <td> Row 2- Col 3 </td>
                <td> Row 2- Col 4 </td>
            </tr>
            <tr>
                <td> Row 3- Col 1 </td>
                <td> Row 3- Col 2 </td>
                <td> Row 3- Col 3 </td>
                <td> Row 3- Col 4 </td>
            </tr>
            <tr>
                <td> Row 4- Col 1 </td>
                <td> Row 4- Col 2 </td>
                <td> Row 4- Col 3 </td>
                <td> Row 4- Col 4 </td>
            </tr>
            <tr>
                <td> Row 5- Col 1 </td>
                <td> Row 5- Col 2 </td>
                <td> Row 5- Col 3 </td>
                <td> Row 5- Col 4 </td>
            </tr>
            <tr>
                <td> Row 6- Col 1 </td>
                <td> Row 6- Col 2 </td>
                <td> Row 6- Col 3 </td>
                <td> Row 6- Col 4 </td>
            </tr>
            <tr>
                <td> Row 7- Col 1 </td>
                <td> Row 7- Col 2 </td>
                <td> Row 7- Col 3 </td>
                <td> Row 7- Col 4 </td>
            </tr>
            <tr>
                <td> Row 8- Col 1 </td>
                <td> Row 8- Col 2 </td>
                <td> Row 8- Col 3 </td>
                <td> Row 8- Col 4 </td>
            </tr>
            <tr>
                <td> Row 9- Col 1 </td>
                <td> Row 9- Col 2 </td>
                <td> Row 9- Col 3 </td>
                <td> Row 9- Col 4 </td>
            </tr>
            <tr>
                <td> Row 10- Col 1 </td>
                <td> Row 10- Col 2 </td>
                <td> Row 10- Col 3 </td>
                <td> Row 10- Col 4 </td>
            </tr>
            <tr>
                <td> Row 11- Col 1 </td>
                <td> Row 11- Col 2 </td>
                <td> Row 11- Col 3 </td>
                <td> Row 11- Col 4 </td>
            </tr>
            <tr>
                <td> Row 12- Col 1 </td>
                <td> Row 12- Col 2 </td>
                <td> Row 12- Col 3 </td>
                <td> Row 12- Col 4 </td>
            </tr>
            <tr>
                <td> Row 13- Col 1 </td>
                <td> Row 13- Col 2 </td>
                <td> Row 13- Col 3 </td>
                <td> Row 13- Col 4 </td>
            </tr>
            <tr>
                <td> Row 14- Col 1 </td>
                <td> Row 14- Col 2 </td>
                <td> Row 14- Col 3 </td>
                <td> Row 14- Col 4 </td>
            </tr>
            <tr>
                <td> Row 15- Col 1 </td>
                <td> Row 15- Col 2 </td>
                <td> Row 15- Col 3 </td>
                <td> Row 15- Col 4 </td>
            </tr>
            <tr>
                <td> Row 16- Col 1 </td>
                <td> Row 16- Col 2 </td>
                <td> Row 16- Col 3 </td>
                <td> Row 16- Col 4 </td>
            </tr>
        </tbody>
    </table>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-slimScroll/1.3.8/jquery.slimscroll.min.js"></script>
    <script>
        $('.example-table tbody').slimscroll({
            height: '160px',
            alwaysVisible: true,
            color: '#333'
        })
    </script>
</body>

</html>


1

Questo è il codice che funziona per me per creare una testa appiccicosa su un tavolo con un corpo scorrevole:

table ,tr td{
    border:1px solid red
}
tbody {
    display:block;
    height:50px;
    overflow:auto;
}
thead, tbody tr {
    display:table;
    width:100%;
    table-layout:fixed;/* even columns width , fix width of table too*/
}
thead {
    width: calc( 100% - 1em )/* scrollbar is average 1em/16px width, remove it from thead width */
}
table {
    width:400px;
}

1

Per usare "overflow: scroll" devi impostare "display: block" su thead e tbody. E questo incasina la larghezza delle colonne tra di loro. Ma poi puoi clonare la riga di thead con Javascript e incollarla nel corpo come una riga nascosta per mantenere le larghezze esatte del col.

$('.myTable thead > tr').clone().appendTo('.myTable tbody').addClass('hidden-to-set-col-widths');

http://jsfiddle.net/Julesezaar/mup0c5hk/

<table class="myTable">
    <thead>
        <tr>
            <td>Problem</td>
            <td>Solution</td>
            <td>blah</td>
            <td>derp</td>
        </tr>
    </thead>
    <tbody></tbody>
</table>
<p>
  Some text to here
</p>

Il css:

table {
  background-color: #aaa;
  width: 100%;
}

thead,
tbody {
  display: block; // Necessary to use overflow: scroll
}

tbody {
  background-color: #ddd;
  height: 150px;
  overflow-y: scroll;
}

tbody tr.hidden-to-set-col-widths,
tbody tr.hidden-to-set-col-widths td {
  visibility: hidden;
  height: 0;
  line-height: 0;
  padding-top: 0;
  padding-bottom: 0;
}

td {
  padding: 3px 10px;
}

0

Prova questo jsfiddle . Questo sta usando jQuery e ricavato dalla risposta di Hashem Qolami. Inizialmente, crea un tavolo normale, quindi rendilo scorrevole.

const makeScrollableTable = function (tableSelector, tbodyHeight) {
  let $table = $(tableSelector);
  let $bodyCells = $table.find('tbody tr:first').children();
  let $headCells = $table.find('thead tr:first').children();
  let headColWidth = 0;
  let bodyColWidth = 0;

  headColWidth = $headCells.map(function () {
    return $(this).outerWidth();
  }).get();
  bodyColWidth = $bodyCells.map(function () {
    return $(this).outerWidth();
  }).get();

  $table.find('thead tr').children().each(function (i, v) {
    $(v).css("width", headColWidth[i]+"px");
    $(v).css("min-width", headColWidth[i]+"px");
    $(v).css("max-width", headColWidth[i]+"px");
  });
  $table.find('tbody tr').children().each(function (i, v) {
    $(v).css("width", bodyColWidth[i]+"px");
    $(v).css("min-width", bodyColWidth[i]+"px");
    $(v).css("max-width", bodyColWidth[i]+"px");
  });

  $table.find('thead').css("display", "block");
  $table.find('tbody').css("display", "block");

  $table.find('tbody').css("height", tbodyHeight+"px");
  $table.find('tbody').css("overflow-y", "auto");
  $table.find('tbody').css("overflow-x", "hidden");

};
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.