Я создал пример скользящей сетки с фиксированными заголовками, используя технологии «CSS Grid Layout» и «липкое положение». Для удобства содержимое сетки генерируется скриптом, который, я думаю, хорошо работает.
function fillGrid(selector, rows) {
let cols = 3;
let grid = $(selector);
grid.empty();
//cr header
grid.append($('<div>').addClass('hcr').text('#'));
//col headers
for (let c = 1; c <= cols; c++) {
grid.append($('<div>').addClass('hc').text(`Column ${c}`));
}
for (let r = 1; r <= rows; r++) {
//row header
grid.append($('<div>').addClass('hr').text(r));
//cells
for (let c = 1; c <= cols; c++) {
grid.append($('<div>').addClass('c').text(`Cell ${r}-${c}`));
}
}
}
$('#reload').click(e => {
var rows = Number.parseInt($('#rows').val());
fillGrid('#grid1', rows);
})
$(document).ready(function() {
fillGrid('#grid1', 10);
});
body {
font-family: 'Segoe UI', sans-serif;
font-size: 12px;
}
.grid {
display: grid;
width: 600px;
height: 300px;
grid-template-columns: 40px 200px 100px 500px;
grid-auto-rows: min-content;
border: 1px solid #ccc;
overflow: scroll;
margin-top: 20px;
background-color: #aaa;
margin-right: 10px;
}
.hcr, .hc, .hr {
background-color: #ddd;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
padding: 2px;
position: sticky;
}
.hcr {
top: 0;
left: 0;
z-index: 1;
text-align: center;
}
.hc {
top: 0;
white-space: nowrap;
}
.hr {
left: 0;
text-align: center;
}
.c {
padding: 2px;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
background-color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input type="text" id="rows" value="10" />
<input type="button" id="reload" value="Reload" />
</div>
<div class="grid" id="grid1"></div>
До 999 рядов сетка работает идеально. Когда загружено более 999 строк, отображаются только ячейки до строки 999, а следующие ячейки неправильно располагаются слева над заголовком строки 999.
Тот же пример корректно работает в Firefox 56 и Edge 16 (версия 16299).
Где я не прав?