Способ подсчета столбцов в адаптивной сетке - PullRequest
5 голосов
/ 17 марта 2019

Хотя я пока не смог найти ответ, вопрос прост: Есть ли способ, , кроме грубой силы, подсчитать количество столбцов в адаптивной сетке?

#grid-container {
  width: 100%;
  height: 85%;
  position: relative;
  padding: var(--gap); /* adjusted with JS to make var(--gap) responsive */
  display: grid;
  grid-gap: var(--gap); /* adjusted with JS to make var(--gap) responsive */
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  box-sizing: border-box;
  background: skyblue;
}

.grid-item {
  width: 100%;
  min-width: 120px;
  max-width: 450px;
  height: ; /* adjusted with JS on resize events to roughly maintain proportions */
  min-height: 192px;
  border-radius: 10px;
  background: #333;
}

Причина, по которой я спрашиваю, состоит в том, что я дал элементам сетки max-width, который вызывает огромный разрыв в самой последней точке останова, который я хотел бы обнаружить вместо установки явного медиазапроса.

enter image description here

1 Ответ

1 голос
/ 19 марта 2019

Я думаю, что самый простой способ без грубой силы - рассмотреть простое деление.Вы можете легко найти ширину контейнера, и каждый столбец определяется как minmax(300px,1fr), а мы знаем gap.Используя всю эту информацию, расчет должен быть выполнен следующим образом:

Если у нас будет N столбцов, то у нас будет N-1 пробелов.Мы также знаем, что W должно быть, по крайней мере, 300px и не может быть больше значения (назовем Wmax).

Предположим, что разрыв равен 10px.

Если N=2 и каждый столбец равен 300px, у нас будет ширина контейнера, равная 300px*2 + 10px*1 = 610px.

Если N=3 и каждый столбец равен 300px, мы получим300px*3 + 10px*2=920px.

Теперь ясно, что если ширина контейнера находится между 610px и 920px, у нас будет 2 столбца, потому что нет места для хранения 3 столбцов, но достаточно места для хранения 2 столбцов, которые мыразверните, чтобы заполнить оставшееся пространство (используя 1fr), поэтому Wmax в этом случае будет (920px - 10px)/2 = 455px.Другими словами, ширина будет варьироваться от 300px до 455px при наличии 2 столбцов.

Поэтому, если мы возьмем формулу 300px*N + 10px*(N-1) = Wc с Wc шириной нашего контейнера, вы увидите, что Nравно 2, когда Wc=610px и 3, когда Wc=920px, и между ними будет результат в [2,3], поэтому мы просто округляем значение до наименьшего (2 в данном случае), и мы получимномер столбца.

Вот базовый пример:

var gap = 10;
var minW = 200;

var Wc = document.querySelector('.grid').offsetWidth;
var N = Math.floor((Wc+gap)/(minW+gap));
console.log(N);


window.addEventListener('resize', function(event){
   Wc = document.querySelector('.grid').offsetWidth;
   N = Math.floor((Wc+gap)/(minW+gap));
   console.log(N);
});
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  grid-gap:10px;
}
span {
  min-height:50px;
  background:red;
}
<div class="grid">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

Если вы не знаете значения промежутка и минимальной ширины, вы можете рассмотреть getComputedStyle(), чтобы получить разные значения.В этом случае N уже должно быть целым числом, так как grid-template-columns даст нам вычисленную ширину каждого столбца (на практике у нас все еще будет некоторая доля из-за округления).

var grid = document.querySelector('.grid');

var gap = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("column-gap"));
var minW = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("grid-template-columns"));

var Wc = document.querySelector('.grid').offsetWidth;
var N = (Wc+gap)/(minW+gap);
console.log(N);


window.addEventListener('resize', function(event){
   Wc = document.querySelector('.grid').offsetWidth;minW = parseFloat(window.getComputedStyle(grid,null).getPropertyValue("grid-template-columns"))
   N = (Wc+gap)/(minW+gap);
   console.log(N);
});
.grid {
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(200px,1fr));
  grid-gap:10px;
}
span {
  min-height:50px;
  background:red;
}
<div class="grid">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>
...