Tabella con intestazione fissa e colonna fissa su puro css


97

Ho bisogno di creare una tabella html (o qualcosa di simile) con un'intestazione fissa e una prima colonna fissa.

Ogni soluzione che ho visto finora utilizza Javascript o jQueryper impostare scrollTop / scrollLeft, ma non funziona correttamente sui browser mobili, quindi sto cercando una soluzione CSS pura.

Ho trovato una soluzione per una colonna fissa qui: jsfiddle.net/C8Dtf/20/ ma non so come migliorarla per correggere anche l'intestazione.

Voglio che funzioni sui browser webkit o usi alcune css3funzionalità, ma ripeto, non voglio usarlo Javascriptper lo scorrimento.

EDIT: Questo è un esempio del comportamento che voglio ottenere: https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size.html


Non vedo dove <html> <table> con intestazione fissa <thead> abbia a che fare con css-level-3 per il momento. Che altro hai ? Cosa hai provato fino ad ora ?
Milche Patern

Ho provato ad applicare un positioncomportamento complesso a righe e celle, ma non capisco bene dove sia applicabile o meno.
panfil

2
Questa risposta può aiutarti a stackoverflow.com/questions/14834198/…
Garry

Risposte:


141

Una vera e propria soluzione CSS pura con una riga di intestazione fissa e una prima colonna

Ho dovuto creare una tabella con un'intestazione fissa e una prima colonna fissa usando puro CSS e nessuna delle risposte qui era proprio quello che volevo.

La position: stickyproprietà supporta sia l'aderenza in alto (come ho visto che è stata usata di più) sia a lato nelle versioni moderne di Chrome, Firefox e Edge. Questo può essere combinato con un divche ha la overflow: scrollproprietà di darti una tabella con intestazioni fisse che possono essere posizionate ovunque sulla tua pagina:

Metti la tua tavola in un contenitore:

<div class="container">
  <table></table>
</div>

Usa overflow: scrollsul tuo contenitore per abilitare lo scorrimento:

div.container {
  overflow: scroll;
}

Come ha sottolineato Dagmar nei commenti, il contenitore richiede anche a max-widthe a max-height.

Utilizzare position: stickyavere celle della tabella fissati al bordo e top, righto leftdi scegliere quale bordo a bastone per:

thead th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  top: 0;
}

tbody th {
  position: -webkit-sticky; /* for Safari */
  position: sticky;
  left: 0;
}

Come MarredCheese menzionato nei commenti, se la tua prima colonna contiene <td>elementi invece di <th>elementi, puoi usarli tbody td:first-childnel tuo CSS invece ditbody th

Per avere l'intestazione nella prima colonna stick a sinistra, usa:

thead th:first-child {
  left: 0;
  z-index: 1;
}

https://jsfiddle.net/qwubvg9m/1/


22
Questa sembra la migliore risposta.
user1190132

9
@PirateApp Se conosci la widthtua prima colonna, puoi usare position: stickysulle celle della tua seconda colonna con un leftvalore uguale a quello della tua prima colonna width: jsfiddle.net/wvypo83c/794
Matthew Schlachter

4
Questa risposta dimostra che ne vale la pena leggere fino in fondo!
mlerley

4
Questo non funziona senza una larghezza massima e un'altezza massima impostate sul contenitore.
Dagmar

9
Questa risposta è un faro che ci guida a casa attraverso il mare infinito di risposte malfunzionanti, troppo complicate e che fanno perdere tempo da poster sorprendentemente sicuri e sconcertanti qui su SO e attraverso il web. Nota che se la tua prima colonna contiene <td>elementi invece di <th>elementi, puoi usarli tbody td:first-childnel tuo CSS invece di tbody th.
MarredCheese

32

Al giorno d'oggi, questo è possibile ottenere utilizzando CSS solo con position: stickyproprietà.

Ecco uno snippet:

(jsFiddle: https://jsfiddle.net/hbqzdzdt/5/ )

.grid-container {
  display: grid; /* This is a (hacky) way to make the .grid element size to fit its content */
  overflow: auto;
  height: 300px;
  width: 600px;
}
.grid {
  display: flex;
  flex-wrap: nowrap;
}
.grid-col {
  width: 150px;
  min-width: 150px;
}

.grid-item--header {
  height: 100px;
  min-height: 100px;
  position: sticky;
  position: -webkit-sticky;
  background: white;
  top: 0;
}

.grid-col--fixed-left {
  position: sticky;
  left: 0;
  z-index: 9998;
  background: white;
}
.grid-col--fixed-right {
  position: sticky;
  right: 0;
  z-index: 9998;
  background: white;
}

.grid-item {
  height: 50px;
  border: 1px solid gray;
}
<div class="grid-container">
  <div class="grid">
    <div class="grid-col grid-col--fixed-left">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
      <div class="grid-item">
        <p>Hello</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
      <div class="grid-item">
        <p>P</p>
      </div>
    </div>

    <div class="grid-col grid-col--fixed-right">
      <div class="grid-item grid-item--header">
        <p>HEAD</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
      <div class="grid-item">
        <p>9</p>
      </div>
    </div>

  </div>
</div>

Per quanto riguarda la compatibilità. Funziona in tutti i principali browser, ma non in IE. C'è un polyfill per position: stickyma non l'ho mai provato.


2
Questo è fantastico, lo adoro!
Capitano Lu

3
qualsiasi modo per ottenere questo risultato con <table> -tag e non con <div>
Andreas

1
Penso che questo non avrà buone prestazioni se stai sviluppando un'applicazione e hai bisogno di scorrere i record per stampare questa tabella perché per ogni colonna della tabella, devi scorrere l'intero array del record. Questo HTML funziona colonna per colonna.
igasparetto

@igasparetto Puoi effettivamente disporre le righe / colonne al contrario e la soluzione funzionerebbe comunque. Se ho tempo dopo posso creare uno snippet con la riga ordinata della griglia -> colonna.
Alvaro

2
Vorrei sconsigliare la visualizzazione di dati tabulari senza utilizzare <table> e tag associati. Ci sono diversi problemi con l'interruzione dell'uso previsto dell'HTML in questo modo, inclusa l'accessibilità. Vedi anche: w3.org/WAI/tutorials/tables
Ben Morris

15

Non è un'impresa facile.

Il seguente collegamento è a una demo funzionante:

Link Aggiornato in base al commento di lanoxx

http://jsfiddle.net/C8Dtf/366/

Ricorda solo di aggiungere questi:

<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>

non vedo nessun altro modo per raggiungere questo obiettivo. Soprattutto non usando solo css.

Questo è molto da affrontare. Spero che questo ti aiuti :)


Per cambiare il filtro utilizzare: "bFilter": false
lanoxx

6
E ' è possibile raggiungere questo obiettivo con solo css. Non facile ma possibile.
Jimmy T.

da circa 10 soluzioni questa era l'unica che ha funzionato. A proposito, per rimuovere "Mostra 1 a 57 di 57 voci" aggiungere "bInfo" : falsenella .dataTable()chiamata
hansaplast

datatables == "awesome"
billynoah

downvoting questa soluzione perché è male. si theadtrova nella propria tabella che non è vincolata alle modifiche degli tdelementi, quindi se il testo di una cella è lungo, la thlarghezza non si adatterà di conseguenza.
vsync

14

Tutti questi suggerimenti sono fantastici e tutti, ma o stanno solo correggendo l'intestazione o una colonna, non entrambi, oppure usano javascript. Il motivo: non crede che possa essere fatto in puro CSS. La ragione:

Se fosse possibile, dovresti annidare diversi div scorrevoli uno dentro l'altro, ciascuno con uno scorrimento in una direzione diversa. Quindi dovresti dividere la tabella in tre parti: l'intestazione fissa, la colonna fissa e il resto dei dati.

Bene. Ma ora il problema: puoi fare in modo che uno di loro rimanga fermo quando scorri, ma l'altro è annidato all'interno dell'area di scorrimento del primo ed è quindi soggetto a scorrere fuori dalla vista stessa, quindi non può essere fissato in posizione su lo schermo. "Ah-ah" dici "ma in qualche modo posso usare la posizione assoluta o fissa per farlo" - no non puoi. Non appena lo fai, perdi la capacità di scorrere quel contenitore. È una situazione di pollo e uova: non puoi averli entrambi, si annullano a vicenda.

Credo che l'unica soluzione sia tramite javascript. È necessario separare completamente i tre elementi e mantenere le loro posizioni sincronizzate tramite javascript. Ci sono buoni esempi in altri post su questa pagina. Anche questo vale la pena dare un'occhiata:

http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/


9

Ho apportato alcune modifiche a jsfiddle. Questo potrebbe essere quello che stai cercando di fare.

http://jsfiddle.net/C8Dtf/81/

Ho codificato i titoli in questo modo:

<table id="left_table" class="freeze_table">
    <tr class='tblTitle'>
         <th>Title 1</th>
         <th>Title 2</th>
    </tr>
</table>

E ho aggiunto anche alcuni stili.

.tblTitle{
   position:absolute;
    top:0px;
    margin-bottom:30px;
    background:lightblue;
}
td, th{
    padding:5px;
    height:40px;
    width:40px;
    font-size:14px;
}

Spero che questo sia quello che vuoi :)


1
Ho bisogno di un'intestazione della tabella di destra per scorrere insieme al suo contenuto.
panfil

Ecco l'URL: jsfiddle.net/C8Dtf/84 . Hai solo bisogno di giocare con lo stile del tavolo di destra per allineare i due tavoli.
Phillip-juan

No. Non capisci bene. Ho bisogno che l'intestazione della tabella di destra sia fissata in alto in modo che sia ancora visibile quando la tabella scorre su e giù, ma quando la tabella scorre a destra o a sinistra l'intestazione deve scorrere a destra oa sinistra ma essere ancora fissata in alto. Scusami per le mie cattive competenze in inglese.
panfil

Quindi vuoi che l'intestazione della tabella di destra venga fissata quando si scorre verticalmente e che scorra quando si scorre in orizzontale?
Phillip-juan

Questo è esempio del comportamento che voglio raggiungere: datatables.net/release-datatables/extras/FixedColumns/...
Panfil

9

Un esempio che utilizza solo CSS:

.table {
  table-layout: fixed;
  width: 500px;
  border-collapse: collapse;
}

.header th {
  font-family: Calibri;
  font-size: small;
  font-weight: lighter;
  border-left: 1px solid #000;
  background: #d0d0d0;
}

.body_panel {
  display: inline-block;
  width: 520px;
  height: 300px;
  overflow-y: scroll;
}

.body tr {
  border-bottom: 1px solid #d0d0d0;
}

.body td {
  border-left: 1px solid #d0d0d0;
  padding-left: 3px;
  font-family: Calibri;
  font-size: small;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
<body>

  <table class="table">

    <thead class="header">

      <tr>
        <th style="width:20%;">teste</th>
        <th style="width:30%;">teste 2</th>
        <th style="width:50%;">teste 3</th>
      </tr>

    </thead>
  </table>

  <div class="body_panel">

    <table class="table">
      <tbody class="body">

        <tr>
          <td style="width:20%;">asbkj k kajsb ksb kabkb</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

        <tr>
          <td style="width:20%;">2</td>
          <td style="width:30%;">2</td>
          <td style="width:50%;">3</td>
        </tr>

      </tbody>
    </table>

  </div>

</body>


3
Avevo bisogno non solo della correzione di heder, ma anche della prima colonna.
panfil

Questo esempio mostra un approccio con due tabelle in html: una tabella esegue il rendering solo dell'intestazione; la seconda tabella esegue il rendering solo delle righe ma lo fa all'interno di un file div. È il divche consente lo scorrimento delle righe mentre l'intestazione rimane nella stessa posizione. Questo approccio ha funzionato per le mie esigenze.
David Tansey

Se c'è anche lo scorrimento orizzontale, è necessario un po 'di JS per sincronizzare le posizioni di scorrimento delle tabelle.
Zoltán Tamási

4

Per correggere sia le intestazioni che le colonne, puoi utilizzare il seguente plug-in:


Aggiornato a luglio 2019

Recentemente è emersa anche una soluzione CSS pura che si basa sulla proprietà CSS position: sticky;( qui per maggiori dettagli a riguardo) applicata su ogni THelemento (invece del loro contenitore genitore)


1
Il primo collegamento è interrotto. Il secondo usa jQuery.
PussInBoots

Risposta aggiornata per rimuovere il collegamento morto
Luca Detomi

3

Ho trovato un'ottima soluzione per il problema da Paul O'Brien e vorrei condividere il link: https://codepen.io/paulobrien/pen/LBrMxa

Ho rimosso lo stile per il piè di pagina:

html {
  box-sizing: border-box;
}
*,
*:before,
*:after {
  box-sizing: inherit;
}
.intro {
  max-width: 1280px;
  margin: 1em auto;
}
.table-scroll {
  position: relative;
  width:100%;
  z-index: 1;
  margin: auto;
  overflow: auto;
  height: 350px;
}
.table-scroll table {
  width: 100%;
  min-width: 1280px;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;
}
.table-wrap {
  position: relative;
}
.table-scroll th,
.table-scroll td {
  padding: 5px 10px;
  border: 1px solid #000;
}
.table-scroll thead th {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

th:first-child {
  position: -webkit-sticky;
  position: sticky;
  left: 0;
  z-index: 2;
  background: #ccc;
}
thead th:first-child {
  z-index: 5;
}

2

Recentemente ho dovuto creare una soluzione con un gruppo di intestazioni fisso e una prima colonna fissa. Ho diviso la mia tabella in div e ho usato jquery per catturare lo scorrimento della finestra.

http://jsfiddle.net/TinT/EzXub/2346/

var prevTop = 0;
var prevLeft = 0;

$(window).scroll(function(event){
  var currentTop = $(this).scrollTop();
  var currentLeft = $(this).scrollLeft();

  if(prevLeft !== currentLeft) {
    prevLeft = currentLeft;
    $('.header').css({'left': -$(this).scrollLeft()})
  }
  if(prevTop !== currentTop) {
    prevTop = currentTop;
    $('.leftCol').css({'top': -$(this).scrollTop() + 40})
  }
});

1

Un collega e io abbiamo appena rilasciato un nuovo progetto GitHub che fornisce una direttiva Angular che puoi utilizzare per decorare la tua tabella con intestazioni fisse: https://github.com/objectcomputing/FixedHeader

Si basa solo su css e angular, con una direttiva che aggiunge alcuni div. Non è richiesto jQuery.

Questa implementazione non è così completa come alcune altre implementazioni, ma se la tua necessità è semplicemente quella di aggiungere tabelle fisse, pensiamo che questa potrebbe essere una buona opzione.


1

Dopo due giorni di lotta con Internet Explorer 9 + Chrome + Firefox (Windows) e Safari (Mac), ho trovato un sistema che è

  • Compatibile con tutti questi browser
  • Senza usare javascript
  • Utilizzando solo une div e una tabella
  • Intestazione e piè di pagina fissi (eccetto IE), con corpo scorrevole. Intestazione e corpo con la stessa larghezza di colonna

Risultato: inserisci qui la descrizione dell'immagine

HTML:

  <thead>
    <tr>
      <th class="nombre"><%= f.label :cost_center %></th>
      <th class="cabecera cc">Personal</th>
      <th class="cabecera cc">Dpto</th>
    </tr>
  </thead>
  <tbody>
    <% @cost_centers.each do |cc| %>
    <tr>
      <td class="nombre"><%= cc.nombre_corto %></td>
      <td class="cc"><%= cc.cacentrocoste %></td>
      <td class="cc"><%= cc.cacentrocoste_dpto %></td>
    </tr>
    <% end %>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3"><a href="#">Mostrar mas usuarios</a></td>
    </tr>
  </tfoot>
</table>

CSS:

div.cost_center{
  width:320px;
  font-size:75%;
  margin-left:5px;
  margin-top:5px;
  margin-bottom: 2px;
  float: right;
  display: inline-block;
  overflow-y: auto;
  overflow-x: hidden;
  max-height:300px;  
}

div.cost_center label { 
  float:none;
  font-size:14px;
}

div.cost_center table{
  width:300px;
  border-collapse: collapse; 
  float:right;
  table-layout:fixed;
}

div.cost_center table tr{
  height:16px;
}
div.cost_center th{
  font-weight:normal;
}

div.cost_center table tbody{
  display: block;
  overflow: auto;
  max-height:240px;
}

div.cost_center table thead{
  display:block;
}

div.cost_center table tfoot{
  display:block;
}
div.cost_center table tfoot td{
  width:280px;
}
div.cost_center .cc{
  width:60px;
  text-align: center; 
  border: 1px solid #999;
}

div.cost_center .nombre{
  width:150px;
}
div.cost_center tbody .nombre{
  border: 1px solid #999;
}

div.cost_center table tfoot td{
 text-align:center;  
 border: 1px solid #999; 
} 

div.cost_center table th, 
div.cost_center table td { 
  padding: 2px;
  vertical-align: middle; 
}

div.cost_center table tbody td {
  white-space: normal;
  font:  .8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: white;
}
div.cost_center table th.cabecera { 
  font:  0.8em/1.4em Verdana, sans-serif;
  color: #000;
  background-color: #FFEAB5;
}

Bel tentativo, ma non funziona troppo bene per me. In questo esempio ( jsfiddle.net/5ka6e ), l'intestazione non viene ridimensionata correttamente. Questo tipo di errore potrebbe finire per avere dati e intestazione non corrispondenti.
darkzangel

1
Dimentichi di aggiungere div.cost_center table{border-collapse: collapse;}e la terza didascalia deve essere qualcosa che si adatta ai 60px (in questo esempio)
Albert Català

1

Le risposte esistenti soddisferanno la maggior parte delle persone, ma per coloro che stanno cercando di aggiungere ombre sotto l'intestazione fissa e a destra della prima colonna (fissa), ecco un esempio funzionante (css puro):

http://jsbin.com/nayifepaxo/1/edit?html,output

Il trucco principale per farlo funzionare è usare ::afterper aggiungere ombre a destra di ciascuna delle prime tdin ciascuna tr:

tr td:first-child:after {
  box-shadow: 15px 0 15px -15px rgba(0, 0, 0, 0.05) inset;
  content: "";
  position:absolute;
  top:0;
  bottom:0;
  right:-15px;
  width:15px;
}

Mi ci è voluto un po '(troppo tempo ...) per far funzionare tutto, quindi ho pensato di condividere per coloro che si trovano in una situazione simile.


Hai basato questo sulla risposta di qualcun altro e hai aggiunto l'ombra?
PussInBoots

1

è necessario correggere il piè di pagina dell'intestazione


0

Qualcosa di simile potrebbe funzionare per te ... Probabilmente ti richiederà di impostare la larghezza delle colonne per la riga di intestazione.

thead { 
    position: fixed;
}

http://jsfiddle.net/vkhNC/

Aggiornare:

Non sono convinto che l'esempio che hai fornito sia possibile solo con i CSS. Mi piacerebbe che qualcuno mi dimostrasse che ho torto. Ecco cosa ho finora . Non è il prodotto finito ma potrebbe essere un inizio per te. Spero che questo ti indichi una direzione utile, ovunque sia.


Ho bisogno non solo dell'intestazione, ma anche della prima colonna.
panfil

5
Il problema è che le intestazioni perdono la loro larghezza. Sembra brutto con diverse dimensioni della colonna di intestazione e dimensioni della colonna di dati.
Akash Kava


0

Esempio CSS puro:

<div id="cntnr">
    <div class="tableHeader">
        <table class="table-header table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>


    <div class="tableBody">
        <table class="table-body table table-striped table-bordered">
            <thead>
                <tr>
                    <th>this</th>
                    <th>transmission</th>
                    <th>is</th>
                    <th>coming</th>
                    <th>to</th>
                    <th>you</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                    <td>we've got it...</td>
                    <td>alright you are go</td>
                    <td>uh, we see the Earth now</td>
                </tr>
            </tbody>
        </table>
    </div>

</div>

#cntnr {
    width: auto;
    height: 200px;
    border: solid 1px #444;
    overflow: auto;
}

.tableHeader {
    position: fixed;
    height: 40px;
    overflow: hidden;
    margin-right: 18px;
    background: white;
}

.table-header tbody {
    height: 0;
    visibility: hidden;
}

.table-body thead {
    height: 0;
    visibility: hidden;
}

http://jsfiddle.net/cCarlson/L98m854d/

Svantaggio: la struttura / logica dell'intestazione fissa dipende abbastanza da dimensioni specifiche, quindi l' astrazione probabilmente non è un'opzione praticabile .


Hai bisogno sia dell'intestazione fissa che della prima colonna fissa.
panfil

Ah ... grazie per averlo fatto notare, panfil. Farò una modifica. Saluti
Cody

0

Posizione: sticky non funziona per alcuni elementi come (thead) in Chrome e altri browser webkit come Safari.

Ma funziona bene con (th)

body {
  background-color: rgba(0, 255, 200, 0.1);
}

.intro {
  color: rgb(228, 23, 23);
}

.wrapper {
  overflow-y: scroll;
  height: 300px;
}

.sticky {
  position: sticky;
  top: 0;
  color: black;
  background-color: white;
}
<div class="container intro">
  <h1>Sticky Table Header</h1>
  <p>Postion : sticky doesn't work for some elements like (thead) in chrome and other webkit browsers like safari. </p>
  <p>But it works fine with (th)</p>
</div>
<div class="container wrapper">
  <table class="table table-striped">
    <thead>
      <tr>
        <th class="sticky">Firstname</th>
        <th class="sticky">Lastname</th>
        <th class="sticky">Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>James</td>
        <td>Vince</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Jonny</td>
        <td>Bairstow</td>
        <td>jonny@example.com</td>
      </tr>
      <tr>
        <td>James</td>
        <td>Anderson</td>
        <td>james@example.com</td>
      </tr>
      <tr>
        <td>Stuart</td>
        <td>Broad</td>
        <td>stuart@example.com</td>
      </tr>
      <tr>
        <td>Eoin</td>
        <td>Morgan</td>
        <td>eoin@example.com</td>
      </tr>
      <tr>
        <td>Joe</td>
        <td>Root</td>
        <td>joe@example.com</td>
      </tr>
      <tr>
        <td>Chris</td>
        <td>Woakes</td>
        <td>chris@example.com</td>
      </tr>
      <tr>
        <td>Liam</td>
        <td>PLunkett</td>
        <td>liam@example.com</td>
      </tr>
      <tr>
        <td>Jason</td>
        <td>Roy</td>
        <td>jason@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Hales</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Jos</td>
        <td>Buttler</td>
        <td>jos@example.com</td>
      </tr>
      <tr>
        <td>Ben</td>
        <td>Stokes</td>
        <td>ben@example.com</td>
      </tr>
      <tr>
        <td>Jofra</td>
        <td>Archer</td>
        <td>jofra@example.com</td>
      </tr>
      <tr>
        <td>Mitchell</td>
        <td>Starc</td>
        <td>mitchell@example.com</td>
      </tr>
      <tr>
        <td>Aaron</td>
        <td>Finch</td>
        <td>aaron@example.com</td>
      </tr>
      <tr>
        <td>David</td>
        <td>Warner</td>
        <td>david@example.com</td>
      </tr>
      <tr>
        <td>Steve</td>
        <td>Smith</td>
        <td>steve@example.com</td>
      </tr>
      <tr>
        <td>Glenn</td>
        <td>Maxwell</td>
        <td>glenn@example.com</td>
      </tr>
      <tr>
        <td>Marcus</td>
        <td>Stoinis</td>
        <td>marcus@example.com</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Carey</td>
        <td>alex@example.com</td>
      </tr>
      <tr>
        <td>Nathan</td>
        <td>Coulter Nile</td>
        <td>nathan@example.com</td>
      </tr>
      <tr>
        <td>Pat</td>
        <td>Cummins</td>
        <td>pat@example.com</td>
      </tr>
      <tr>
        <td>Adam</td>
        <td>Zampa</td>
        <td>zampa@example.com</td>
      </tr>
    </tbody>
  </table>
</div>

Oppure visita il mio esempio di codepen :



-2

Se vuoi usare solo HTML e CSS puri, ho una soluzione per il tuo problema:
in questo jsFiddle puoi vedere una soluzione non script che fornisce una tabella con un'intestazione fissa. Non dovrebbe essere un problema adattare il markup anche per una prima colonna fissa. Dovresti solo creare una tabella con posizionamento assoluto per la prima colonna all'interno di hWrapper-div e riposizionare vWrapper-div.
Fornire contenuti dinamici non dovrebbe essere un problema utilizzando motori allettanti lato server o lato browser, la mia soluzione funziona bene in tutti i browser moderni e browser meno recenti da IE8 in poi.


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.