Макет сетки с реагирующими квадратами

Я хочу создать сетку с чувствительными квадратами.

Мне кажется, что я смогу сделать это с помощью макета CSS Grid, но проблема с установкой высоты каждого квадрата равным ширине.

Также возникает проблема с установкой желоба между каждым квадратом.

Будет ли лучше использовать flexbox?

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

<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

Используя сетку css, это насколько я получил

.square-container{
    display: grid;
    grid-template-columns: 30% 30% 30%;
    .square {

    }
}

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

Мне не удалось найти примеры того, как это делается с помощью flexbox или сетки, но любые примеры также будут оценены.

Спасибо

Ответ 1

padding-bottom трюка наиболее часто используемый для достижения этой цели.

Вы можете комбинировать его как с Flexbox, так и с CSS Grid, и поскольку использование процентов для полей/отступов дает противоречивый результат для элементов flex/grid, можно добавить дополнительную оболочку или, как здесь, использовать псевдо, так что элемент с процентами не является элемент flex/grid.


Изменить: Обратите внимание, что обновление сделано для спецификации. , что теперь должно давать последовательный результат при использовании на элементах flex/grid. Имейте в виду, что проблема все еще возникает в старых версиях.


Обратите внимание: если вы добавите контент к элементу content, он должен быть абсолютным, чтобы сохранить квадратное соотношение сторон.

Демонстрация скрипки - Flexbox

.square-container {
  display: flex;
  flex-wrap: wrap;
}

.square {
  position: relative;
  flex-basis: calc(33.333% - 10px);
  margin: 5px;
  border: 1px solid;
  box-sizing: border-box;
}

.square::before {
  content: '';
  display: block;
  padding-top: 100%;
}

.square .content {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  width: 100%;
}
<div class="square-container">

  <div class="square">
    <div class="content">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

  <div class="square">
    <div class="content spread">
    </div>
  </div>

  <div class="square">
    <div class="content column">
    </div>
  </div>

</div>

Ответ 2

Попробуйте использовать процентные единицы просмотрa > .

jsFiddle

.square-container {
  display: grid;
  grid-template-columns: repeat(3, 30vw);
  grid-template-rows: 30vw;
  grid-gap: 2.5vw;
  padding: 2.5vw;
  background-color: gray;
}

.square {
  background-color: lightgreen;
}

body {
  margin: 0; /* remove default margins */
}
<div class="square-container">
  <div class="square">
    <div class="content"></div>
  </div>
  <div class="square">
    <div class="content spread"></div>
  </div>
  <div class="square">
    <div class="content column"></div>
  </div>
</div>

Ответ 3

Вы можете использовать тот факт, что отступ рассчитывается на основе ширины и установить padding-top: 100% непосредственно для элементов square сетки (элементы сетки теперь будут квадратными).


Обновление 2019

Обратите внимание, что для гибких элементов, а также элементов сетки ранее это не работало - см. Сообщение, связанное в комментариях к этому ответу:

Теперь, когда между браузерами (более новыми версиями) существует консенсус в отношении одинакового поведения для padding для гибких элементов и элементов сетки, вы можете использовать это решение.

Смотрите демо ниже:

.square-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
  grid-gap: 10px;
}

.square {
  background: cadetblue;
  padding-top: 100%; /* padding trick directly on the grid item */
  box-sizing: border-box;
  position: relative;
}

.square .content { /* absolutely positioned */
  position: absolute;
  top: 0;
  right:0;
  left: 0;
  bottom: 0;
}
<div class="square-container">
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content"> some content here</div>
  </div>
  <div class="square">
    <div class="content column">some content here and there is a lot of text here</div>
  </div>
  <div class="square">
    <div class="content spread">text</div>
  </div>
  <div class="square">
    <div class="content column">some text here</div>
  </div>
</div>