Tabel dengan header tetap dan kolom tetap pada css murni

97

Saya perlu membuat tabel html (atau yang terlihat serupa) dengan header tetap dan kolom pertama tetap.

Setiap solusi yang saya lihat sejauh ini menggunakan Javascript atau jQueryuntuk mengatur scrollTop / scrollLeft, tetapi tidak bekerja dengan lancar di browser seluler, jadi saya mencari solusi CSS murni.

Saya menemukan solusi untuk kolom tetap di sini: jsfiddle.net/C8Dtf/20/ tetapi saya tidak tahu bagaimana saya dapat meningkatkannya untuk membuat tajuk tetap juga.

Saya ingin ini berfungsi di browser webkit atau menggunakan beberapa css3fitur, tetapi saya ulangi, saya tidak ingin menggunakan Javascriptuntuk scrolling.

EDIT: Ini adalah contoh perilaku yang ingin saya capai: https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size.html

panfil
sumber
Saya tidak melihat di mana <html> <table> dengan header tetap <thead> ada hubungannya dengan css-level-3 untuk saat ini. Apa lagi yang kamu punya Apa yang sudah kamu coba sejauh ini?
Milche Patern
Saya telah mencoba menerapkan positionperilaku kompleks ke baris dan sel, tetapi saya tidak begitu mengerti di mana hal itu dapat diterapkan atau tidak.
panfil
2
Jawaban ini dapat membantu Anda stackoverflow.com/questions/14834198/…
Garry

Jawaban:

141

Solusi CSS murni aktual dengan baris tajuk tetap dan kolom pertama

Saya harus membuat tabel dengan header tetap dan kolom pertama tetap menggunakan CSS murni dan tidak ada jawaban di sini yang sesuai dengan yang saya inginkan.

The position: stickyproperti mendukung kedua mencuat ke atas (seperti yang telah saya melihatnya digunakan paling) dan ke sisi dalam versi modern dari Chrome, Firefox, dan Edge. Ini dapat dikombinasikan dengan divyang memiliki overflow: scrollproperti untuk memberi Anda tabel dengan header tetap yang dapat ditempatkan di mana saja di halaman Anda:

Tempatkan meja Anda dalam wadah:

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

Gunakan overflow: scrolldi penampung Anda untuk mengaktifkan pengguliran:

div.container {
  overflow: scroll;
}

Seperti yang ditunjukkan Dagmar di komentarnya, container juga membutuhkan a max-widthdan a max-height.

Gunakan position: stickyuntuk memiliki sel tabel tongkat ke tepi dan top, right, atau leftuntuk memilih tepi untuk menempel:

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

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

Seperti yang disebutkan MarredCheese di komentar, jika kolom pertama Anda berisi <td>elemen, bukan <th>elemen, Anda dapat menggunakan tbody td:first-childdi CSS daripadatbody th

Agar tajuk di kolom pertama menempel di kiri, gunakan:

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

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

Matthew Schlachter
sumber
22
Sepertinya ini jawaban terbaik.
user1190132
9
@PirateApp Jika Anda mengetahui widthkolom pertama Anda, Anda dapat menggunakan position: stickypada sel di kolom kedua dengan leftnilai yang sama dengan kolom pertama Anda width: jsfiddle.net/wvypo83c/794
Matthew Schlachter
4
Jawaban ini membuktikan bahwa bacaan itu layak dibaca sampai habis!
mlerley
4
Ini tidak akan berfungsi tanpa set lebar-maksimal dan tinggi-maksimal pada penampung.
Dagmar
9
Jawaban ini adalah mercusuar yang memandu kita pulang melalui lautan tak berujung jawaban yang tidak berfungsi, terlalu rumit, dan membuang-buang waktu dari poster yang sangat percaya diri dan mendapat suara tinggi di sini di SO dan di seluruh web. Perhatikan bahwa jika kolom pertama Anda berisi <td>elemen, bukan <th>elemen, Anda dapat menggunakan tbody td:first-childCSS sebagai ganti tbody th.
MarredCheese
32

Saat ini, ini dimungkinkan untuk dicapai dengan menggunakan CSS hanya dengan position: stickyproperti.

Ini dia cuplikannya:

(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>

Mengenai kompatibilitas. Ia bekerja di semua browser utama, tetapi tidak di IE. Ada polyfill untuk position: stickytapi saya tidak pernah mencobanya.

Alvaro
sumber
2
Ini bagus, suka!
Kapten Lu
3
cara apa pun untuk mencapai ini dengan <table> -tags dan bukan <div>
Andreas
1
Saya pikir ini tidak akan memiliki kinerja yang baik jika Anda sedang mengembangkan aplikasi dan perlu melakukan loop melalui record untuk mencetak tabel ini karena untuk setiap kolom dalam tabel, Anda harus melakukan loop melalui seluruh array record. HTML ini bekerja kolom demi kolom.
igasparetto
@igasparetto Anda sebenarnya dapat mengatur baris / kolom secara terbalik dan solusinya akan tetap berfungsi. Jika saya punya waktu kemudian saya dapat membuat potongan dengan baris urutan grid -> kolom.
Alvaro
2
Saya akan menyarankan agar tidak menampilkan data tabel tanpa menggunakan <tabel> dan tag terkait. Ada beberapa masalah dengan melanggar tujuan penggunaan HTML dengan cara ini, termasuk aksesibilitas. Lihat juga: w3.org/WAI/tutorials/tables
Ben Morris
15

Ini bukanlah hal yang mudah.

Tautan berikut adalah ke demo kerja:

Tautan Diperbarui menurut komentar lanoxx

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

Ingatlah untuk menambahkan ini:

<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>

saya tidak melihat cara lain untuk mencapai ini. Apalagi dengan menggunakan css saja.

Ini banyak yang harus dilalui. Semoga ini membantu :)

Phillip-juan
sumber
Untuk mengganti penggunaan filter: "bFilter": false
lanoxx
6
Hal ini dimungkinkan untuk mencapai ini hanya dengan css. Tidak mudah tapi mungkin.
Jimmy T.
dari sekitar 10 solusi, inilah satu-satunya yang berhasil. Btw, untuk menghapus "Menampilkan 1 hingga 57 dari 57 entri" tambahkan "bInfo" : falseke dalam .dataTable()panggilan
hansaplast
datatables == "mengagumkan"
billynoah
downvoting solusi ini karena buruk. yang theadada di meja sendiri yang tidak terikat dengan perubahan dari tdelemen, jadi jika teks sel panjang, thlebar tidak akan menyesuaikan sesuai.
vsync
14

Semua saran ini bagus dan semuanya, tetapi hanya memperbaiki header atau kolom, tidak keduanya, atau menggunakan javascript. Alasan - tidak percaya itu bisa dilakukan dengan CSS murni. Alasannya:

Jika memungkinkan untuk melakukannya, Anda perlu menumpuk beberapa div yang dapat digulir satu di dalam yang lain, masing-masing dengan gulir ke arah yang berbeda. Kemudian Anda perlu membagi tabel Anda menjadi tiga bagian - header tetap, kolom tetap, dan data lainnya.

Baik. Tapi sekarang masalahnya - Anda dapat membuat salah satunya tetap diam saat Anda menggulir, tetapi yang lain bersarang di dalam area gulir terlebih dahulu dan karena itu dapat di-scroll sehingga tidak terlihat itu sendiri, jadi tidak dapat diperbaiki pada tempatnya layar. 'Ah-ha' Anda mengatakan 'tetapi saya entah bagaimana bisa menggunakan posisi absolut atau tetap untuk melakukan itu' - tidak, Anda tidak bisa. Segera setelah Anda melakukannya, Anda kehilangan kemampuan untuk menggulir penampung itu. Ini adalah situasi ayam dan telur - Anda tidak dapat memiliki keduanya, keduanya membatalkan satu sama lain.

Saya yakin satu-satunya solusi adalah melalui javascript. Anda harus benar-benar memisahkan ketiga elemen dan menjaga posisinya tetap sinkron melalui javascript. Ada contoh bagus di posting lain di halaman ini. Yang ini juga patut untuk dilihat:

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

PretorianNZ
sumber
9

Saya telah membuat beberapa perubahan di jsfiddle. Ini mungkin yang Anda coba lakukan.

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

Saya telah membuat hardcode judul seperti ini:

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

Dan saya menambahkan beberapa gaya juga.

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

Semoga ini yang Anda inginkan :)

Phillip-juan
sumber
1
Saya membutuhkan header dari tabel yang tepat untuk menggulir bersama dengan isinya.
panfil
Ini URL-nya: jsfiddle.net/C8Dtf/84 . Anda hanya perlu bermain-main dengan gaya untuk tabel kanan untuk menyelaraskan kedua tabel.
Phillip-juan
Tidak. Anda tidak begitu mengerti. Saya membutuhkan header dari tabel kanan untuk diperbaiki ke atas sehingga akan tetap terlihat ketika tabel di-scroll ke atas dan ke bawah, tetapi ketika tabel di-scroll header kanan atau kiri harus di-scroll ke kanan atau ke kiri tetapi tetap diperbaiki di atas. Maaf atas kemampuan bahasa Inggris saya yang buruk.
panfil
Jadi ingin tajuk tabel di sebelah kanan diperbaiki saat menggulir secara vertikal, dan menggulir saat menggulir secara horizontal?
Phillip-juan
Ini adalah contoh perilaku yang ingin saya capai: datatables.net/release-datatables/extras/FixedColumns/…
panfil
9

Contoh hanya menggunakan 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>

Dyego.JhOu
sumber
3
Saya tidak hanya membutuhkan heder yang diperbaiki, tetapi kolom pertama juga.
panfil
Contoh ini menunjukkan pendekatan dengan dua tabel di html: satu tabel hanya menampilkan header; tabel kedua merender baris saja tetapi melakukannya dalam a div. Ini adalah divyang memungkinkan pengguliran baris sementara header tetap di tempat yang sama. Pendekatan ini berhasil untuk kebutuhan saya.
David Tansey
Jika ada pengguliran horizontal juga, Anda memerlukan beberapa JS untuk menyinkronkan posisi gulir tabel.
Zoltán Tamási
4

Untuk memperbaiki Header dan Kolom, Anda dapat menggunakan plugin berikut:


Diperbarui pada Juli 2019

Baru-baru ini muncul juga solusi CSS murni yang didasarkan pada properti CSS position: sticky;(di sini untuk detail lebih lanjut tentangnya) diterapkan ke setiap THitem (bukan wadah induknya)

Luca Detomi
sumber
1
Tautan pertama rusak. Yang kedua menggunakan jQuery.
PussInBoots
Jawaban yang diperbarui untuk menghapus tautan mati
Luca Detomi
3

Saya menemukan solusi luar biasa dari Paul O'Brien untuk masalah ini dan ingin membagikan tautannya: https://codepen.io/paulobrien/pen/LBrMxa

Saya menghapus gaya untuk footer:

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;
}
Artiom Kozyrev
sumber
2

Saya baru-baru ini harus membuat solusi dengan grup header tetap dan kolom pertama tetap. Saya membagi tabel saya menjadi div dan menggunakan jquery untuk menangkap window scrolling.

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})
  }
});
Tristan
sumber
1

Seorang rekan kerja dan saya baru saja merilis proyek GitHub baru yang menyediakan arahan Angular yang dapat Anda gunakan untuk mendekorasi meja Anda dengan header tetap: https://github.com/objectcomputing/FixedHeader

Ini bergantung pada css dan angular saja, dengan arahan yang menambahkan beberapa div. Tidak diperlukan jQuery.

Implementasi ini tidak berfitur lengkap seperti beberapa implementasi lainnya, tetapi jika kebutuhan Anda hanya untuk menambahkan tabel tetap, menurut kami ini mungkin pilihan yang baik.

pengguna3221325
sumber
1

Setelah dua hari berkelahi dengan Internet Explorer 9 + Chrome + Firefox (Windows) dan Safari (Mac), saya telah menemukan sistem yang

  • Kompatibel dengan semua browser ini
  • Tanpa menggunakan javascript
  • Hanya menggunakan une div dan satu tabel
  • Memperbaiki header dan footer (Kecuali untuk IE), dengan isi yang dapat digulir. Header dan body dengan lebar kolom yang sama

Hasil: masukkan deskripsi gambar di sini

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;
}
Albert Català
sumber
Usaha yang bagus, tapi tidak terlalu berhasil untuk saya. Dalam contoh ini ( jsfiddle.net/5ka6e ), ukuran header tidak diubah dengan benar. Jenis error ini pada akhirnya bisa mengakibatkan ketidakcocokan data dan header.
darkzangel
1
Anda lupa menambahkan div.cost_center table{border-collapse: collapse;}dan teks ketiga harus sesuai dengan ukuran 60px (dalam contoh ini)
Albert Català
1

Jawaban yang ada akan cocok untuk kebanyakan orang, tetapi bagi mereka yang ingin menambahkan bayangan di bawah tajuk tetap dan di sebelah kanan kolom pertama (tetap), berikut adalah contoh yang berfungsi (css murni):

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

Trik utama untuk membuatnya bekerja adalah menggunakan ::afteruntuk menambahkan bayangan di sebelah kanan masing-masing yang pertama tddi masing-masing 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;
}

Butuh waktu lama (terlalu lama ...) untuk menyelesaikan semuanya, jadi saya pikir saya akan berbagi untuk mereka yang berada dalam situasi yang sama.


sumber
Apakah Anda mendasarkan ini pada jawaban orang lain dan menambahkan bayangan?
PussInBoots
1

perlu memperbaiki footer header

neel upadhyay
sumber
0

Sesuatu seperti ini mungkin berhasil untuk Anda ... Ini mungkin akan meminta Anda untuk mengatur lebar kolom untuk baris tajuk Anda.

thead { 
    position: fixed;
}

http://jsfiddle.net/vkhNC/

Memperbarui:

Saya tidak yakin bahwa contoh yang Anda berikan dimungkinkan hanya dengan CSS. Saya ingin seseorang membuktikan bahwa saya salah. Inilah yang saya miliki sejauh ini . Ini bukan produk jadi tetapi bisa menjadi awal untuk Anda. Saya harap ini mengarahkan Anda ke arah yang membantu, di mana pun itu.

bradj
sumber
Saya tidak hanya membutuhkan header, tetapi kolom pertama juga diperbaiki.
panfil
5
Masalahnya adalah header kehilangan lebarnya. Tampak jelek dengan ukuran kolom header dan ukuran kolom data yang berbeda.
Akash Kava
0

Solusi lain adalah dengan menggunakan AngularJS. Modul AngularUI memiliki direktif yang disebut ng-gridyang mendukung fitur yang disebut penyematan kolom. Ini bukan CSS murni 100% tetapi juga bukan solusi lainnya.

http://angular-ui.github.io/ng-grid/#columnPinning

lanoxx.dll
sumber
0

Contoh CSS Murni:

<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/

Kekurangan: Logika / struktur header tetap sangat bergantung pada dimensi tertentu, jadi abstraksi mungkin bukan pilihan yang tepat .

Cody
sumber
Perlu tajuk tetap dan kolom pertama tetap.
panfil
Ah ... terima kasih sudah menunjukkan ini, panfil. Saya akan mengedit. Cheers
Cody
0

Posisi: sticky tidak berfungsi untuk beberapa elemen seperti (thead) di chrome dan browser webkit lainnya seperti safari.

Tapi itu bekerja dengan baik dengan (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>[email protected]</td>
      </tr>
      <tr>
        <td>Jonny</td>
        <td>Bairstow</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>James</td>
        <td>Anderson</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Stuart</td>
        <td>Broad</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Eoin</td>
        <td>Morgan</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Joe</td>
        <td>Root</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Chris</td>
        <td>Woakes</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Liam</td>
        <td>PLunkett</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Jason</td>
        <td>Roy</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Hales</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Jos</td>
        <td>Buttler</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Ben</td>
        <td>Stokes</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Jofra</td>
        <td>Archer</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Mitchell</td>
        <td>Starc</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Aaron</td>
        <td>Finch</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>David</td>
        <td>Warner</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Steve</td>
        <td>Smith</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Glenn</td>
        <td>Maxwell</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Marcus</td>
        <td>Stoinis</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Alex</td>
        <td>Carey</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Nathan</td>
        <td>Coulter Nile</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Pat</td>
        <td>Cummins</td>
        <td>[email protected]</td>
      </tr>
      <tr>
        <td>Adam</td>
        <td>Zampa</td>
        <td>[email protected]</td>
      </tr>
    </tbody>
  </table>
</div>

Atau kunjungi contoh codepen saya :

Yoga
sumber
-1

Saya rasa ini akan membantu Anda: https://datatables.net/release-datatables/extensions/FixedHeader/examples/header_footer.html

Singkatnya, jika Anda tahu cara membuat dataTable, Anda hanya perlu menambahkan baris jQuery ini ke bawah:

$(document).ready(function() {
    var table = $('#example').DataTable();

    new $.fn.dataTable.FixedHeader( table, {
        bottom: true
    } );
} );

bottom: true // untuk memperbaiki header Bawah.

JackSparrow
sumber
-2

Jika Anda hanya ingin menggunakan HTML dan CSS murni, saya punya solusi untuk masalah Anda:
Di jsFiddle ini Anda dapat melihat solusi non-skrip yang menyediakan tabel dengan header tetap. Seharusnya tidak menjadi masalah untuk menyesuaikan markup untuk kolom pertama tetap juga. Anda hanya perlu membuat tabel dengan posisi absolut untuk kolom pertama di dalam hWrapper-div dan memposisikan ulang vWrapper-div.
Menyediakan konten dinamis seharusnya tidak menjadi masalah menggunakan mesin penggoda sisi server atau sisi browser, solusi saya berfungsi dengan baik di semua browser modern dan browser lama dari IE8 dan seterusnya.

Lukas Hechenberger
sumber
-2

Hanya perlu mengubah gaya sebagai

<table style="position: relative;">
   <thead>
      <thead>
        <tr>
           <th></th>
        </tr>
      </thead>
   </thead>
   <tbody style="position: absolute;height: 300px;overflow:auto;">
      <tr>
         <td></td>
      </tr>
   </tbody>
</table>

Demo: https://plnkr.co/edit/Qxy5RMJBXmkaJAOjBtQn?p=preview

Omprakash Sharma
sumber
2
dalam demo Anda, kolom pertama tidak diperbaiki
Bravo