Scroll bar horizontal ekstra pada tabel HTML header tetap?
Saya punya beberapa tabel HTML dengan banyak kolom. Saat ini saya mencoba meningkatkan tabel ini agar memiliki header tetap, jadi saya melihat contoh online yang mengatakan untuk membuat tata letak tabel tetap, blok thead dan tbody, membatasi tinggi untuk tbody, dan mengatur overflow-y pada tbody. Itu semua berfungsi dengan baik, data saya bergulir sementara header tetap di tempat.
Namun, setiap kali saya memiliki cukup kolom yang lebarnya melebihi viewport, saya mendapatkan dua scrollbar horizontal yang tidak saya minta. Saya tidak menyetel overflow atau overflow-x di mana pun, namun saya mendapatkan dua scrollbar horizontal - satu untuk tbody saja, dan satu untuk seluruh tabel. Menggulir dengan tbody satu menampilkan semua data tetapi meninggalkan header pada tempatnya sehingga tidak sejajar dengan data, dan menggulir tabel tidak memungkinkan Anda untuk melihat data melewati viewport asli karena ada bilah gulir vertikal di mana tepi kanan viewport aslinya.
Saya sebenarnya menggunakan versi lama Vuetify (tidak, saya tidak dapat meningkatkan), tetapi saya telah mempersempit banyak hal dan mereproduksi masalah dengan contoh sederhana HTML / CSS saja di sini . Adakah yang bisa menjelaskan kepada saya dari mana scrollbar horizontal berasal? Saya ingin satu scrollbar horizontal, mungkin satu untuk tabel, tetapi saya ingin scrollbar data dan header. Mungkin menghapus scrollbar tbody akan melakukannya, tetapi saya tidak mendefinisikannya di mana pun, jadi saya tidak tahu cara menghapusnya. Nyatanya, inspektur tidak menampilkan overflow-x sama sekali! Saya telah mencoba menambahkan overflow-x ke berbagai elemen untuk mencoba memaksa scrollbar sehingga yang otomatis ini tidak perlu muncul, tetapi sejauh ini tidak berhasil.
Terima kasih sebelumnya atas saran apa pun!
Contoh CSS:
table {
table-layout: fixed;
width: 100%;
}
thead tr, tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: auto;
}
th, td {
width: 100px;
min-width: 100px;
}
Contoh HTML:
<html>
<div style="max-width: 500px; overflow-y: auto;">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td>
<td>Data2</td>
<td>Data3</td>
<td>Data4</td>
<td>Data5</td>
<td>Data6</td>
<td>Data7</td>
<td>Data8</td>
<tr>
<tr>
<td>Data1</td>
<td>Data2</td>
<td>Data3</td>
<td>Data4</td>
<td>Data5</td>
<td>Data6</td>
<td>Data7</td>
<td>Data8</td>
<tr>
<!-- more rows to make it scroll vertically -->
</tbody>
</table>
</div>
</html>
Jawaban
Scrollbar yang Anda bicarakan sedang ditambahkan ke tbodyelemen. Dengan berubah tbodymenjadi blok, overscroll:autoditambahkan secara default, meskipun Anda hanya memasukkan overflow-yCSS Anda:
thead tr, tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: auto;
}
Solusi Parsial ( berfungsi bila tidak ada luapan horizontal )
Menambahkan overflow-y:hiddenke tbodyakan menghapus bilah gulir horizontal kedua, dan ini berfungsi bila tidak ada luapan horizontal. Namun jika ada, scrollbar vertikal "macet" ke kolom yang diposisikan pada lebar-maksimal dan menggulir dengan tbody, seperti yang Anda lihat di sini:
table {
table-layout: fixed;
width: 100%;
}
thead tr, tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: auto;
overflow-x: hidden;
}
th, td {
width: 100px;
min-width: 100px;
}
<html>
<div style="max-width: 500px; overflow-y: auto;">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
</tbody>
</table>
</div>
</html>
Masalah besarnya adalah bahwa membuat tbodyscroll secara independen dari theadvertikal (yang kami inginkan karena kami ingin mempertahankan heading) juga menghentikannya bekerja pada scroll horizontal (yang tidak kami lakukan karena heading tidak bergerak dengan tbody).
Solusi khusus CSS untuk overflow horizontal & vertikal ( dukungan browser parsial )
Menggunakan position:stickyuntuk baris tajuk akan membuatnya tetap diposisikan di bagian atas tabel saat tabel lainnya menggulir di belakangnya:
th {
position: sticky;
top: 0;
background: #FFF; /* otherwise we can see the scrolling data behind it */
}
table {
/* prevent the th scrolling up by the default border size before "sticking" */
border-collapse: collapse;
}
Namun ini hanya memiliki dukungan browser parsial . Perhatikan bahwa ini hanya berfungsi th(dan tidak theadatau tr) di Chrome, FF, dan lainnya.
Contoh Kerja (atau tidak, tergantung pada browser Anda!):
table {
table-layout: fixed;
width: 100%;
/* the prevents the th scrolling up by the default border size before "sticking" */
border-collapse: collapse;
}
th, td {
width: 100px;
min-width: 100px;
}
th {
position: sticky;
top: 0;
background: #FFF;
}
<html>
<p>This is some content to show the effect of the sticky header and top:0 on the rest of the page </p>
<div style="max-width: 500px; height:200px; overflow: auto;">
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
</tbody>
</table>
</div>
<p>This is some content to show the effect of the sticky header and top:0 on the rest of the page </p>
</html>
Solusi Javascript / jQuery
Ini ditandai sebagai CSS & HTML, tetapi saya hanya akan menyebutkan ini di sini karena JS adalah satu-satunya cara yang pasti untuk melakukan ini dengan dukungan browser terluas.
- Codepen dari "Springborg" dengan 2 opsi: https://codepen.io/springborg/pen/MvPmPP
- Pertanyaan SO ini memiliki berbagai cara untuk mengkloning tabel untuk membuat baris header secara terpisah: Memperbaiki header tabel dengan badan scrolling horizontal DAN vertikal
Jawaban Salman A dari pertanyaan itu membuat tabel klon, dan menampilkan <thead>dari pertama dan <tbody>dari yang kedua. Ini mudah diterapkan dalam contoh Anda - lihat di bawah:
$(function() { $(".fixed_headers").each(function() {
$(this).wrap("<div class='scrollable-table'></div>"); $(this).clone().insertBefore(this);
});
});
.scrollable-table {
overflow: auto;
max-height: 200px;
}
.scrollable-table table:nth-child(1) {
position: sticky;
left: 0;
top: 0;
background-color: #fff;
margin-bottom: 0;
}
.scrollable-table table:nth-child(1) tbody {
visibility: collapse;
}
.scrollable-table table:nth-child(2) thead {
visibility: collapse;
}
th, td {
width: 100px;
min-width: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<div style="max-width: 500px;">
<table class="fixed_headers">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
<th>Column 6</th>
<th>Column 7</th>
<th>Column 8</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
<tr>
<td>Data1</td><td>Data2</td><td>Data3</td><td>Data4</td>
<td>Data5</td><td>Data6</td><td>Data7</td><td>Data8</td>
</tr>
</tbody>
</table>
</div>
</html>
Coba kode ini:
table {
table-layout: fixed;
width: 100%;
overflow: hidden; // New Entry
}
Secara default, nilai overflow terlihat untuk x dan y Tapi t-body Anda lagi menggunakan overflow-y: auto; karena itu terjadi dan dua gulir ditampilkan.