CSS Grid Layout в Chrome, кажется, не работает должным образом с более чем 1000 строк

Я создал пример скользящей сетки с фиксированными заголовками, используя технологии «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).

Где я не прав?


person Bludev    schedule 10.11.2017    source источник


Ответы (3)


Хорошо, ограничение в 1000 строк (а также 1000 столбцов) было намеренно введено в движок Chrome из соображений стабильности и потребления оперативной памяти. Похоже, что новая версия функциональности Grid находится в разработке и должна решить проблему.

Источники:

person Bludev    schedule 17.11.2017

Я сделал ручку, которая реализует возможный обходной путь для этой проблемы: 10K Rows CSS Grid Table

Короче говоря, решение состоит в том, чтобы отображать только видимые строки на основе положения прокрутки. Невидимые строки должны быть заменены одной строкой, заполняющей промежутки, которая получает их общую высоту. Этот метод известен как виртуализация или окно.

Чтобы сделать его оптимистичным, эта строка, заполняющая пробелы, должна также получить градиентный фон, который имитирует горизонтальные линии строки, чтобы он выглядел так, как будто линии есть (поскольку эта строка будет ненадолго видна, когда пользователь прокручивает, и мы не хотим он должен быть пустым).

С точки зрения производительности таблица из 100 строк будет работать точно так же, как таблица из 10 000 строк при применении этого решения.

Например:

<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>
person Yoav Kadosh    schedule 03.07.2019

В зависимости от вашего макета вы также можете заменить display: grid на display: block.

Если в вашей таблице несколько столбцов, вам, возможно, придется обернуть элементы для каждой строки, но у меня это сработало отлично.

Разрыв сетки можно воспроизвести с помощью margin-top.

person ST-DDT    schedule 08.04.2021