I have created an example of a sliding grid with fixed headers, using the "CSS Grid Layout" and "sticky position" technologies. For convenience, the content of the grid is generated by a script, which I think works well.
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>
Up to 999 rows the grid works perfectly. When more than 999 rows are loaded, only the cells up to row 999 are displayed, while the following cells are incorrectly positioned on the left above the header of row 999.
The same example works correctly in Firefox 56 and Edge 16 (version 16299).
Where am I wrong?
The supporting browsers Other than in Internet Explorer, CSS Grid Layout is unprefixed in Safari, Chrome, Opera, Firefox and Edge.
The problem is that you are applying the grid-template-columns property to grid items. This is a grid container property. It will be ignored on grid items (unless they are also grid containers). Instead use the grid-column and grid-row properties, which apply to grid items.
The vertical gaps are caused by the images not filling the vertical space in the grid items. The problem is made worse with align-items: center on the container, which removes the align-items: stretch default. Essentially, there are no gaps between grid items.
Basics & Browser Support As of March 2017, most browsers shipped native, unprefixed support for CSS Grid: Chrome (including on Android), Firefox, Safari (including on iOS), and Opera.
Ok, the 1000 rows (and also 1000 columns) limit has been intentionally introduced into the Chrome engine for reasons of stability and RAM consumption. A new version of the Grid functionality seems to be in progress and should solve the problem.
Sources:
UPD: from Chrome version 96.0.4642 items amount extended to 100,000 rows/columns
I've made a pen that implements a possible workaround to this issue: 10K Rows CSS Grid Table
In short - the solution is to only render the visible rows based on the scroll position. The non-visible rows should be replaced with a single "gap-filling" row that receives their total height. This technique is known as virtualization or windowing.
To make it "optimistic", that gap-filling row should also receive a gradient background that simulates the horizontal row lines to make it look as if the lines are there (since this row will be briefly visible as the user scrolls and we don't want it to be blank).
In terms of performance, a table of 100 rows will perform exactly the same as a table with 10K rows when applying this solution.
For example:
<div class="table">
<div class="gap-before"
style="height: {{total height of rows before the visible rows}}">
<!-- visible rows go here -->
<div class="gap-after"
style="height: {{total height of rows after the visible rows}}">
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With