#html #css #html-table #sticky
#HTML #css #html-таблица #липкий
Вопрос:
Учитывая следующую структуру таблицы:
<table border="1px">
<thead>
<tr>
<td rowspan="2">Item No</td>
<th colspan="2">Store ABC</th>
<th colspan="2">Store DEF</th>
</tr>
<tr>
<th>Baskets</th>
<th>Customers</th>
<th>Baskets</th>
<th>Customers</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Я хотел бы сделать заголовок таблицы липким, чтобы при прокрутке таблицы он оставался видимым.
Простая вещь, когда есть только одна строка заголовка. Однако при наличии двух все становится сложнее. Я придумал следующий css:
thead th, thead td {
position: sticky;
top: 0;
background: #eee;
}
Это «почти» работает, за исключением того, что при прокрутке таблицы две строки заголовка как бы «скользят» в одну и ту же позицию, причем вторая строка находится поверх первой.
Как сделать две строки заголовка липкими таким образом, чтобы их внешний вид не менялся при прокрутке таблицы вниз (т. Е. Весь заголовок остается «блоком», а две его отдельные строки остаются на месте)?
Обязательный jsFiddle: http://jsfiddle.net/juyvcLd6/3 /
— ОБНОВИТЬ
Идентификация двух строк заголовка с class="first"
помощью и class="second"
соответственно, плюс добавление следующего css:
thead tr.first th, thead tr.first td {
position: sticky;
top: 0;
background: #eee;
}
thead tr.second th, thead tr.second td {
position: sticky;
top: 17px;
background: #eee;
}
позволяет сохранять строки заголовка вместе на месте при прокрутке таблицы. Однако top: 17px
элемент очень сильно зависит от фактического отображаемого размера строки. Например, если браузер пользователя по-разному отображает размеры текста, тогда все отключится.
Кроме того, у этого метода есть недостаток в том, что он довольно странным образом избавляется от границ заголовка.
Как убедиться, что при прокрутке таблицы:
top: xxx
правило для второй строки на самом деле отражает реальную высоту первой строки?- границы остаются в соответствии с тем, как они выглядят, когда таблица не прокручивается?
Смотрите обновленный jsFiddle: http://jsfiddle.net/juyvcLd6/4 /
Комментарии:
1. Ваш подход tr.first и tr.second спас положение. Спасибо!
2. В большинстве случаев вполне допустимо принять фиксированную высоту для некоторых ваших ячеек заголовка, и этот тип решения работает как шарм, без необходимости грубых взломов JS.
Ответ №1:
Вы можете удалить ‘top’ из ad tr.second th, ad tr.second td и добавить jquery для получения и установки высоты второго заголовка
$(document).ready(function() {
var firstheight = $('.first').height();
$("thead tr.second th, thead tr.second td").css("top", firstheight)
});
table {
height: 100%;
border-collapse: collapse;
width: 100%;
margin: 10px;
font-size: 0.8em;
}
thead tr.first th, thead tr.first td {
position: sticky;
position: -webkit-sticky; /* Safari */
top: 0;
background: #eee;
}
thead tr.second th, thead tr.second td {
position: sticky;
position: -webkit-sticky; /* Safari */
background: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1px">
<thead>
<tr class="first">
<td rowspan="2">Item No</td>
<th colspan="2">Store ABC</th>
<th colspan="2">Store DEF</th>
</tr>
<tr class="second">
<th>Baskets</th>
<th>Customers</th>
<th>Baskets</th>
<th>Customers</th>
</tr>
</thead>
<tbody>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
</tbody>
</table>
Комментарии:
1. Интересно. Хотя jQuery здесь определенно не вариант (попытка оставаться чистым), этот подход имеет смысл и идеально применим с ванильным JavaScript.
Ответ №2:
Поскольку все ваши строки заголовка находятся внутри thead
, просто примените position: sticky;
к thead
вместо thead th, thead td
. Таким образом, вам не нужно беспокоиться о высоте каждой строки заголовка или о том, сколько строк заголовка у вас есть.
thead {
position: sticky;
top: 0;
background: #eee;
}
Я внес изменения в ваш первый пример, и это работает. https://jsfiddle.net/qcuxkng5 /
table {
height: 100%;
border-collapse: collapse;
width: 100%;
margin: 10px;
font-size: 0.8em;
}
thead {
position: sticky;
top: 0;
background: #eee;
}
<table border="1px">
<thead>
<tr>
<td rowspan="2">Item No</td>
<th colspan="2">Store ABC</th>
<th colspan="2">Store DEF</th>
</tr>
<tr>
<th>Baskets</th>
<th>Customers</th>
<th>Baskets</th>
<th>Customers</th>
</tr>
</thead>
<tbody>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
<tr>
<th>123</th>
<td>345</td>
<td>345</td>
<td>345</td>
<td>345</td>
</tr>
</tbody>
</table>
Комментарии:
1. Хороший простой ответ на мою проблему, и jQuery не требуется. Моя верхняя строка заголовка прокручивалась, а 2-я была исправлена, когда мой css применял position: sticky; и top: 0; к элементам <th> . Помещение их в класс, который применяется только к <thead>, как вы описали, сделало свое дело!
2. Это работало для меня в последних версиях firefox и chromium, но не в qtwebengine (который основан на chromium).