Come visualizzare la barra di scorrimento su una tabella html


86

Sto scrivendo una pagina in cui ho bisogno di una tabella html per mantenere una dimensione impostata. Ho bisogno che le intestazioni nella parte superiore della tabella rimangano sempre lì, ma ho anche bisogno che il corpo della tabella scorra indipendentemente dal numero di righe aggiunte alla tabella.

Voglio che assomigli al metodo 2 in questo URL: http://www.cssplay.co.uk/menu/tablescroll.html

Ho provato a farlo ma non viene visualizzata alcuna barra di scorrimento:

tbody {
  height: 80em;
  overflow: scroll;
}
<table border=1 id="qandatbl" align="center">
  <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
  </tr>

  <tbody>
    <tr>
      <td class='qid'></td>
      <td class="options"></td>
      <td class="duration"></td>
    </tr>
  </tbody>
</table>


Perché non usi il codice dal metodo di esempio? <tbody>Sfortunatamente non puoi usare .
Mike Park

Risposte:


164

Qualcosa come questo?

http://jsfiddle.net/TweNm/

L'idea è di racchiudere il <table>in un posizionamento non statico <div>che abbia una overflow:autoproprietà CSS. Quindi posizionare gli elementi <thead>nell'assoluto.

#table-wrapper {
  position:relative;
}
#table-scroll {
  height:150px;
  overflow:auto;  
  margin-top:20px;
}
#table-wrapper table {
  width:100%;

}
#table-wrapper table * {
  background:yellow;
  color:black;
}
#table-wrapper table thead th .text {
  position:absolute;   
  top:-20px;
  z-index:2;
  height:20px;
  width:35%;
  border:1px solid red;
}
<div id="table-wrapper">
  <div id="table-scroll">
    <table>
        <thead>
            <tr>
                <th><span class="text">A</span></th>
                <th><span class="text">B</span></th>
                <th><span class="text">C</span></th>
            </tr>
        </thead>
        <tbody>
          <tr> <td>1, 0</td> <td>2, 0</td> <td>3, 0</td> </tr>
          <tr> <td>1, 1</td> <td>2, 1</td> <td>3, 1</td> </tr>
          <tr> <td>1, 2</td> <td>2, 2</td> <td>3, 2</td> </tr>
          <tr> <td>1, 3</td> <td>2, 3</td> <td>3, 3</td> </tr>
          <tr> <td>1, 4</td> <td>2, 4</td> <td>3, 4</td> </tr>
          <tr> <td>1, 5</td> <td>2, 5</td> <td>3, 5</td> </tr>
          <tr> <td>1, 6</td> <td>2, 6</td> <td>3, 6</td> </tr>
          <tr> <td>1, 7</td> <td>2, 7</td> <td>3, 7</td> </tr>
          <tr> <td>1, 8</td> <td>2, 8</td> <td>3, 8</td> </tr>
          <tr> <td>1, 9</td> <td>2, 9</td> <td>3, 9</td> </tr>
          <tr> <td>1, 10</td> <td>2, 10</td> <td>3, 10</td> </tr>
          <!-- etc... -->
          <tr> <td>1, 99</td> <td>2, 99</td> <td>3, 99</td> </tr>
        </tbody>
    </table>
  </div>
</div>


15
Che ne dici di nessuna colonna a larghezza fissa?
Fractaliste

3
Ho provato la tua risposta ma le colonne di intestazione non sono allineate. Ho usato solo il tuo css in un tag di stile all'interno del tag body dove ho copiato la tua tabella
Antonio

Ottima soluzione, ma ho problemi con essa. Quando si tenta di nascondere una riga e impostare la visualizzazione: nessuno ci sono degli spazi bianchi tra le righe. Questo non è il caso della tabella normale. Qualche idea, consiglio o suggerimento?
Daniil Shevelev

@Antonio: ho avuto lo stesso problema (le colonne di intestazione centrate * sembravano non allineate), ma l'aggiunta ha transform: translateX(-50%)fatto il trucco per me [* centrato è lo stile standard in Firefox che viene rimosso dall'opzione "normalizza CSS" nel JSFiddle di questa risposta]
Sora.

46

Devi inserire il tuo <table>in un <div>che ha dimensioni fisse e in <div>stile devi impostare overflow: scroll.


1
ha dato un'altezza di 500 px per il mio div e ha funzionato bene. <div style = "overflow: scroll; height: 500px;">
Ziggler

3
Non so perché tutti lo abbiano reso così complicato. Questa dovrebbe essere la risposta accettata.
amallard

1
Questa è di gran lunga la soluzione più semplice. Potrebbero esserci delle avvertenze per aggiungere un div con un overflow e un'altezza fissa, ma questa soluzione ti metterà almeno nella giusta direzione.
lsimonetti

1
Superba risposta amico! Saluti a te
:)

1
Questa dovrebbe essere la risposta accettata. Semplice, dritto al punto e con esso non distruggo nient'altro.
Ci provo così tanto ma piango più forte il

40

La risposta accettata ha fornito un buon punto di partenza, ma se ridimensionate la cornice, modificate la larghezza delle colonne o addirittura modificate i dati della tabella, le intestazioni verranno confuse in vari modi. Ogni altro esempio che ho visto ha problemi simili o impone alcune serie restrizioni sul layout della tabella.

Penso di aver finalmente risolto tutti questi problemi. Ci sono voluti molti CSS, ma il prodotto finale è affidabile e facile da usare quanto una normale tabella.

Ecco un esempio che ha tutte le funzionalità richieste per replicare la tabella a cui fa riferimento l'OP: jsFiddle

I colori e i bordi dovrebbero essere modificati per renderlo identico al riferimento. Le informazioni su come apportare questo tipo di modifiche sono fornite nei commenti CSS.

Ecco il codice:

/*the following html and body rule sets are required only if using a % width or height*/
/*html {
width: 100%;
height: 100%;
}*/
body {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0 20px 0 20px;
  text-align: center;
  background: white;
}
.scrollingtable {
  box-sizing: border-box;
  display: inline-block;
  vertical-align: middle;
  overflow: hidden;
  width: auto; /*if you want a fixed width, set it here, else set to auto*/
  min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/
  height: 188px/*100%*/; /*set table height here; can be fixed value or %*/
  min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/
  font-family: Verdana, Tahoma, sans-serif;
  font-size: 15px;
  line-height: 20px;
  padding: 20px 0 20px 0; /*need enough padding to make room for caption*/
  text-align: left;
}
.scrollingtable * {box-sizing: border-box;}
.scrollingtable > div {
  position: relative;
  border-top: 1px solid black;
  height: 100%;
  padding-top: 20px; /*this determines column header height*/
}
.scrollingtable > div:before {
  top: 0;
  background: cornflowerblue; /*header row background color*/
}
.scrollingtable > div:before,
.scrollingtable > div > div:after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 100%;
  height: 100%;
  left: 0;
}
.scrollingtable > div > div {
  min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/
  max-height: 100%;
  overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/
  overflow-x: hidden;
  border: 1px solid black; /*border around table body*/
}
.scrollingtable > div > div:after {background: white;} /*match page background color*/
.scrollingtable > div > div > table {
  width: 100%;
  border-spacing: 0;
  margin-top: -20px; /*inverse of column header height*/
  /*margin-right: 17px;*/ /*uncomment if using % width*/
}
.scrollingtable > div > div > table > caption {
  position: absolute;
  top: -20px; /*inverse of caption height*/
  margin-top: -1px; /*inverse of border-width*/
  width: 100%;
  font-weight: bold;
  text-align: center;
}
.scrollingtable > div > div > table > * > tr > * {padding: 0;}
.scrollingtable > div > div > table > thead {
  vertical-align: bottom;
  white-space: nowrap;
  text-align: center;
}
.scrollingtable > div > div > table > thead > tr > * > div {
  display: inline-block;
  padding: 0 6px 0 6px; /*header cell padding*/
}
.scrollingtable > div > div > table > thead > tr > :first-child:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 20px; /*match column header height*/
  border-left: 1px solid black; /*leftmost header border*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,
.scrollingtable > div > div > table > thead > tr > * + :before {
  position: absolute;
  top: 0;
  white-space: pre-wrap;
  color: white; /*header row font color*/
}
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}
.scrollingtable > div > div > table > thead > tr > * + :before {
  content: "";
  display: block;
  min-height: 20px; /*match column header height*/
  padding-top: 1px;
  border-left: 1px solid black; /*borders between header cells*/
}
.scrollingtable .scrollbarhead {float: right;}
.scrollingtable .scrollbarhead:before {
  position: absolute;
  width: 100px;
  top: -1px; /*inverse border-width*/
  background: white; /*match page background color*/
}
.scrollingtable > div > div > table > tbody > tr:after {
  content: "";
  display: table-cell;
  position: relative;
  padding: 0;
  border-top: 1px solid black;
  top: -1px; /*inverse of border width*/
}
.scrollingtable > div > div > table > tbody {vertical-align: top;}
.scrollingtable > div > div > table > tbody > tr {background: white;}
.scrollingtable > div > div > table > tbody > tr > * {
  border-bottom: 1px solid black;
  padding: 0 6px 0 6px;
  height: 20px; /*match column header height*/
}
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
<div class="scrollingtable">
  <div>
    <div>
      <table>
        <caption>Top Caption</caption>
        <thead>
          <tr>
            <th><div label="Column 1"></div></th>
            <th><div label="Column 2"></div></th>
            <th><div label="Column 3"></div></th>
            <th>
              <!--more versatile way of doing column label; requires 2 identical copies of label-->
              <div><div>Column 4</div><div>Column 4</div></div>
            </th>
            <th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->
          </tr>
        </thead>
        <tbody>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
          <tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>
        </tbody>
      </table>
    </div>
    Faux bottom caption
  </div>
</div>

<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->


lavoro fantastico. Tuttavia, ho una tabella con 15 colonne e ora non riesco a contenere la tabella nella pagina senza una barra di scorrimento orizzontale. Ho provato a modificare il tuo css, il tuo css splendidamente codificato, per ospitare colonne con larghezza più dinamica, ma nulla che cambio oltre alla larghezza della tabella fa la differenza. Se cambio la larghezza della tabella al 100%, la tabella viene visualizzata nella larghezza della tabella, ma poiché le larghezze delle colonne non si avvolgono, non riesco ancora a vedere tutte le 15 colonne di dati. Ho quasi un tavolo a scorrimento che sembra un po 'kewl, quindi qualsiasi aiuto è apprezzato.
nanker

oh aspetta un secondo, nessuna barra di scorrimento orizzontale, la tabella si interrompe.
nanker

@nanker Se hai bisogno dello scorrimento orizzontale e sei disposto a utilizzare un po 'di JavaScript, dovresti controllare questa risposta . È il modo migliore per creare una tabella a scorrimento di cui sono a conoscenza. Non c'era un buon modo per eseguire lo scorrimento orizzontale con solo CSS quando ho postato questa risposta, ma non l'ho esaminato per un po ', quindi non so cosa sia possibile ora.
DoctorDestructo

Ottimo lavoro. Potresti commentare come modificare più righe di intestazione? La semplice ripetizione del <tr><th></th>..</tr>costrutto chiaramente non funziona. Grazie.
David I. McIntosh

@ DavidI.McIntosh Un'intestazione a più righe sarebbe complicata utilizzando questa tecnica. L'aggiunta di righe sarebbe facile, ma non sono sicuro di come ottenere i bordi orizzontali tra di loro. Potresti provare la soluzione JavaScript che ho collegato nel mio commento precedente a meno che non sia possibile utilizzare JS per qualche motivo.
DoctorDestructo

3

Ho risolto questo problema separando il mio contenuto in due tabelle.

Una tabella è la riga di intestazione.

Anche i secondi sono <table>tag, ma racchiusi in <div>altezza statica e scorrimento di overflow.


1

Vale la pena notare che a seconda del tuo scopo (il mio era i risultati di riempimento automatico di una barra di ricerca) potresti volere che l'altezza sia modificabile e che la barra di scorrimento esista solo se l'altezza lo supera.

Se lo desideri, sostituisci height: x;con max-height: x;e overflow:scrollcon overflow:auto.

Inoltre, puoi usare overflow-xe overflow-yse vuoi, e ovviamente la stessa cosa funziona orizzontalmente conwidth : x;


0

Se arrivi al punto in cui tutte le soluzioni menzionate non funzionano (come è successo per me), fai questo:

  • Crea due tabelle. Uno per l'intestazione e un altro per il corpo
  • Assegna alle due tabelle contenitori / div principali diversi
  • Definisci lo stile del div della seconda tabella per consentire lo scorrimento verticale del suo contenuto.

In questo modo, nel tuo HTML

<div class="table-header-class">
    <table>
       <thead>
          <tr>
            <th>Ava</th>
            <th>Alexis</th>
            <th>Mcclure</th>
          </tr>
       </thead>
    </table>
</div>
<div class="table-content-class">
   <table>
       <tbody>
          <tr>
            <td>I am the boss</td>
            <td>No, da-da is not the boss!</td>
            <td>Alexis, I am the boss, right?</td>
          </tr>
       </tbody>
    </table>
</div>

Quindi modella il genitore della seconda tabella per consentire lo scorrimento verticale, nel tuo CSS

    .table-content-class {
        overflow-y: scroll;    // use auto; or scroll; to allow vertical scrolling; 
        overflow-x: hidden;    // disable horizontal scroll 
    }

Questa è la stessa implementazione della risposta di Zvi un anno prima.
TylerH

0

basta aggiungere sul tavolo

style="overflow-x:auto;"

<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">
    <tr>
    <th class="col1">Question No</th>
    <th class="col2">Option Type</th>
    <th class="col1">Duration</th>
    </tr>

   <tbody>
    <tr>
    <td class='qid'></td>
    <td class="options"></td>
    <td class="duration"></td>
    </tr>
    </tbody>
</table>

style = "overflow-x: auto;" `


La domanda era come far scorrere verticalmente il corpo di una tabella mentre l'intestazione della colonna rimane ferma.
giraffedata

0

Molto facile, basta avvolgere la tabella in un div che ha overflow-y:scroll;e overflow-x:scrollproprietà e fare in modo che il div abbia una larghezza e una lunghezza inferiori rispetto alla tabella. FUNZIONERÀ!!!


Va bene, lo aggiungerò nella prossima risposta.
Ospite

Va bene, l'ho fatto, non so ancora come indentare correttamente il codice in caso di overflow dello stack.
Ospite

0

Il CSS: div{ overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; } table{ width:50px; height:50px; }

Puoi fare in modo che il tavolo e il DIV attorno al tavolo abbiano le dimensioni che desideri, assicurati solo che il DIV sia più piccolo del tavolo. DEVI contenere la tabella all'interno del DIV.

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.