问题
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?
回答1:
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:
- https://bugs.chromium.org/p/chromium/issues/detail?id=688640
- https://github.com/w3c/csswg-drafts/issues/1009
回答2:
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.
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>
来源:https://stackoverflow.com/questions/47218341/css-grid-layout-in-chrome-seems-not-to-work-properly-with-more-than-1000-rows