Css grid - как равномерно разделить по количеству элементов

Я изучаю сетку в CSS, чтобы попытаться разделить строку с помощью этого кода.

.grid-sample {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    row-gap: 4rem;
    padding: 0 5rem; 
}

Насколько я понимаю, строка grid-template-columns: 1fr ... помогает разделить строку на 4 четных столбца.

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

Заранее спасибо!

только с css, исходя из количества элементов, я так не думаю. С CSS, основанным на ширине и высоте, это так. С javacript, исходя из количества элементов, это так.

pier farrugia 11.04.2023 18:58

Сетка @pierfarrugia имеет различные автоматические настройки, которые регулируют ситуацию.

A Haworth 11.04.2023 19:17
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
2
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это можно реализовать с помощью сетки CSS, используя grid-auto-columns и установив grid-auto-flow на columns:

document.querySelector('button').addEventListener('click', (e) => {
  let button = e.currentTarget,
    parent = button.nextElementSibling,
    newChild = document.createElement('span');

  parent.append(newChild);
});
.grid-sample {
  display: grid;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  gap: 4rem;
  padding: 0 5rem;
  /* purely to generate content, otherwise irrelevant */
  counter-reset: childCounter;
  margin-block: 1rem;
}

span {
  background-color: hsl(250deg 90% 85% / 1);
  text-align: center;
}

span::before {
  content: counter(childCounter, decimal-leading-zero);
  counter-increment: childCounter;
}
<div class = "grid-sample">
  <span></span>
</div>

<div class = "grid-sample">
  <span></span>
  <span></span>
  <span></span>
</div>



<div class = "grid-sample">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<div class = "grid-sample">
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

<button type = "button">Add span</button>
<div class = "grid-sample">
  <span></span>
</div>

Демонстрация JS Fiddle.

Стоит отметить, что у этого есть неприятная проблема, заключающаяся в том, что новые элементы продолжают размещаться в новых столбцах (как указывает grid-auto-flow), а не переносятся на новую строку, когда пространство максимально заполнено.

Учитывая эту ситуацию, может быть лучше использовать макет flex-box, например:

document.querySelector('button').addEventListener('click', (e) => {
  let button = e.currentTarget,
    parents = document.querySelectorAll('section > div'),
    newChild = document.createElement('span');

  parents.forEach(
    (el) => el.append(newChild.cloneNode())
  )
});
section {
  box-sizing: border-box;
  inline-size: clamp(40rem, 90%, 1100px);
  margin-inline: auto;
  padding: 0;
}

.grid-sample,
.flex-sample {
  gap: 2rem;
  padding: 0 2rem;
  /* purely to generate content, otherwise irrelevant */
  counter-reset: childCounter;
  margin-block: 1rem;
}

.grid-sample {
  display: grid;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
}

.flex-sample {
  display: flex;
  flex-flow: row wrap;
  justify-content: start;
}

span {
  background-color: hsl(250deg 90% 85% / 1);
  flex-grow: 1;
  padding: 0.5rem;
  text-align: center;
}

span::before {
  content: counter(childCounter, decimal-leading-zero);
  counter-increment: childCounter;
}
<button>Add new child</button>
<section>
  <div class = "grid-sample">
    <span></span>
  </div>
</section>
<section>
  <div class = "flex-sample">
    <span></span>
  </div>
</section>

Демонстрация JS Fiddle.

Использованная литература:

Другие вопросы по теме