Как я могу создать контейнер flexbox, который растягивается, чтобы соответствовать обернутым элементам?

Мне нужен контейнер flex-direction: column; flexbox, ширина которого увеличивается, чтобы соответствовать содержащим элементам.

В этом коде:

Screenshot of codepen

Серый div является контейнером flexbox, а красные div содержатся внутри и выкладываются в столбцах с flexbox. Серая div должна расширять/сокращать ширину, чтобы полностью содержать красные дочерние div. Возможно ли это?

.container {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  max-height: 290px;
  align-content: flex-start;
  padding: 2px;
  background: grey;
}
.child {
  background: red;
  width: 100px;
  height: 100px;
  margin: 2px;
}
<div class="container">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

Ответ 1

"Решение"

Я использую термин "решение" легко, поскольку это безумно трудно обойтись без фиксированных строк, как предложил Томас (т.е. без изменения HTML к более традиционному стилю) или вообще без какой-либо высокой степени взлома, Кроме того, половинки высоты, если только две строки не завершены, а содержащий div не может быть уменьшен в размерах надежно; прокомментируйте ребенка 7 и посмотрите, что произойдет. Затем, когда вы также раскомментируете 8, посмотрите, что он возвращается к "нормальному".

Я чашу около часа, и самое лучшее, что я могу придумать, - это эта скрипка.


Я хотел бы предложить небольшой фон

Значение по умолчанию flex-flow равно row nowrap, это устанавливает определенную ширину x для элемента, которому повезло, чтобы получить это правило. Похоже, что в этом случае изменение flex-flow до column не означает reset ширину x, определенную на этом элементе. Элемент принимает ширину x, как если бы она была flex-flow: row nowrap (попробуйте это для себя).

Здесь возникает целая проблема с наложением на ширину ширины, мы не можем установить свойство flex-basis (оно не должно вести себя так, как я полагаю), поэтому нам нужно обернуть все в другой элемент .container, который мы можем определите ширину и поместите фактические стили столбцов на элемент .row. Однако .container также не будет сокращаться. В лучшем случае наш столбец правильно определен по ширине с элементом .container (ing) для того, чтобы они выполняли свою собственную вещь.

Таким образом, нам нужен псевдоэлемент ::after, чтобы обеспечить фон с правильной шириной, включая некоторые margin и calc() хаки для имитации заполнения.

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

Если вы хотите добавить больше строк, вам нужно будет изменить ширину с 50% на 2 (1/2), до 33% на 3 (1/3) и т.д.... это не так масштабируется, как редактирование сам HTML.

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

Ответ 2

Вы не задали поведение ширины родительского элемента. Задайте свойство отображения контейнера для встроенного блока и для каждого элемента .row добавить отображение: свойство flex.

.container {
  display: inline-block;
  max-height: 290px;
  padding: 2px;
  background: grey;
}
.row{
  display:flex;
}
.child {
  background: red;
  width: 100px;
  height: 100px;
  margin: 2px;
}
<div class="container">
  <div class="row">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
  </div>
  <div class="row">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
  </div>
</div>