Есть ли библиотека или конструктор сетки c Javascript на основе блочной верстки?

Задача: Создать 20 карточек, по три в каждой строке, а оставшиеся две распределить с шириной 50% от ширины контейнера. То есть по 33 все кроме последних 2-ух. На самом деле общее кол-во карточек может быть любым, главное тут кол-во карточек в каждой строке, а если их становиться меньше, то необходимо сменить ширину.

Главное не использовать flex grid и любые другие новомодные css решения для расположения элементов, а использовать только div c float и clearfix.


Ответы (2 шт):

Автор решения: Danila

Задачка, кстати, любопытная. Не уверен, что можно решить без js (но если кто-то подскажет, будет круто). Я предлагаю следующую логику:

  1. Считаем количество блоков
  2. Делим это количество на 3 и анализируем остаток от деления:
    • если он равен 0, то ширина всех блоков 33.333%;
    • если он равен 3, то ширина всех блоков кроме последнего 33.333%, а последнего 100%;
    • если он равен 7 (по идее должен 6, но js округляет до 7 - не важно), то ширина всех блоков кроме последних двух 33.333%, а их 50%.

/* получаем количество блоков */
let length = $('.inner').length;

/*
- делим количество блоков на 3;
- с помощью toFixed(1) получаем число с одним знаком после точки (например, 2.3);
- с помощью split('.') разделяем это число на массив ['2','3'];
- c помощью pop() получаем последний элемент массива, т.е 3;

примечание: знак '+' в самом начале записи позволяет привести строковое значение к числу
*/
let num = +(length/3).toFixed(1).split('.').pop();

if(num == 0) {
  $('.inner').css('width','33.333%')
}
else if(num == 3) {
  $('.inner').css('width','33.333%');
  $('.inner:last-child').css('width','100%')
}
else if(num == 7) {
  $('.inner').css('width','33.333%');
  $('.inner:last-child, .inner:nth-last-child(2)').css('width','50%')
}
* {
  box-sizing: border-box;
}
.wrapper {
  border: 1px solid red;
  display: flex;
  flex-wrap: wrap;
}
.inner {
  border: 1px solid green;
  padding: 30px;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="inner">1</div>
  <div class="inner">2</div>
  <div class="inner">3</div>
  <div class="inner">4</div>
  <div class="inner">5</div>
  <div class="inner">6</div>
  <div class="inner">7</div>
  <div class="inner">8</div>
  <!--<div class="inner">9</div>
  <div class="inner">10</div>
  <div class="inner">11</div>-->
</div>

→ Ссылка
Автор решения: novvember

Непонятно, почему флекс новомодный, но на нем такое делается несложно и он везде поддерживается. Еслия правильно понял, то вот:

.items {
  list-style: none;
  margin: 0;
  padding: 0;
  background-color: #ddd;
  
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px;
}

.item {
  background-color: #aaa;
  min-height: 50px;
  
  width: calc(33.3% - 2 * 10px / 3);
  flex-grow: 1;
}
<ul class="items">
  <li class="item">1</li>
  <li class="item">2</li>
  <li class="item">3</li>
  <li class="item">4</li>
  <li class="item">5</li>
  <li class="item">6</li>
  <li class="item">7</li>
  <li class="item">8</li>
</ul>

→ Ссылка