Есть ли способ иметь повторяющиеся столбцы, которые сжимаются, чтобы соответствовать содержимому в сетке CSS?

#css #css-grid

Вопрос:

Существует ли конфигурация сетки CSS, которая будет повторять (переносить) ячейки, но динамически сжимать столбцы в зависимости от размера содержимого вместо использования столбцов одинакового размера?

Например, вот конфигурация, использующая следующие правила:

 display: grid;
grid-template-columns: repeat(auto-fit, 186px);
grid-auto-columns: min-content;
 

пример сетки 1

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

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

пример сетки 2

обратите внимание, что последняя колонка теперь уже, чем остальные.

Кажется, что сетка-шаблон-столбцы: повтор(); принимает два аргумента. Первая из которых может быть автоматической подгонкой или автоматической заливкой, но вторая должна быть определенной ширины. Есть ли какой-либо способ разрешить автоматическое вычисление этого параметра на основе ширины содержимого?

Вот кодовая панель, с которой я играл, чтобы попытаться достичь этого.

Вот и сценарий реального мира:

пример из реального мира

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

Я знаком с flexbox, но еще не очень хорошо знаком с сеткой. Любые рекомендации здесь были бы весьма признательны.

Ответ №1:

Вы можете создавать повторяющиеся столбцы, соответствующие содержимому, но для столбцов с фиксированным количеством. При использовании auto-fit auto-fill grid генерирует все ячейки одинаковой ширины.

В вашем случае это выглядит как 3×3.

 display: grid;
grid-template-columns: repeat(3, min-content);
 
 *,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: grid;
  place-items: center;
  background-color: hsl(215, 100%, 98%);
  position: relative;
  overflow-x: hidden;
}

.container {
  background-color: lightgray;
  width: 760px;
  display: grid;
  grid-template-columns: repeat(3, min-content);
  resize: horizontal;
  overflow: hidden;
  gap: 5px;
  justify-items: center;
  align-items: center;
}

.child {
  background-color: gray;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

p {
  text-align: center;
} 
 <div class="container">
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/80x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/120x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/160x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/80x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/120x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/160x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/80x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/120x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/160x75" alt="" />
  </div>
</div> 

Кажется, что сетка-шаблон-столбцы: повтор(); принимает два аргумента. Первая из которых может быть автоматической подгонкой или автоматической заливкой, но вторая должна быть определенной ширины. Есть ли какой-либо способ разрешить автоматическое вычисление этого параметра на основе ширины содержимого?

В repeat() функции вы можете использовать другую функцию minmax() в качестве второго свойства. Но это не решит вашу проблему, потому что первый параметр определяет минимальную ширину, например 186 пикселей, а второй-насколько она будет расширяться.

 display: grid;
grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
 
 *,
::after,
::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  display: grid;
  place-items: center;
  background-color: hsl(215, 100%, 98%);
  position: relative;
  overflow-x: hidden;
}

.container {
  background-color: lightgray;
  width: 760px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
  resize: horizontal;
  overflow: hidden;
  gap: 5px;
  justify-items: center;
  align-items: center;
}

.child {
  background-color: gray;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

p {
  text-align: center;
} 
 <div class="container">
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/80x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/120x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/160x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/80x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/120x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/160x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/80x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/120x75" alt="" />
  </div>
  <div class="child">
    <p>title</p>
    <img src="https://via.placeholder.com/160x75" alt="" />
  </div>
</div>