Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Grid Layout in Chrome seems not to work properly with more than 1000 rows

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?

like image 859
Bludev Avatar asked Nov 10 '17 08:11

Bludev


People also ask

Does CSS Grid work in Chrome?

The supporting browsers Other than in Internet Explorer, CSS Grid Layout is unprefixed in Safari, Chrome, Opera, Firefox and Edge.

Why is grid template columns not working CSS?

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.

Why are there gaps in my grid CSS?

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.

Is CSS Grid fully supported?

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.


2 Answers

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

UPD: from Chrome version 96.0.4642 items amount extended to 100,000 rows/columns

like image 65
Bludev Avatar answered Oct 15 '22 23:10

Bludev


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>
like image 44
Yoav Kadosh Avatar answered Oct 16 '22 01:10

Yoav Kadosh