Подтвердить что ты не робот

Как начать новый столбец в формате переноса столбцов Flex

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

  • Должен использовать flex (мне нужно использовать функцию, специфичную для flex)
  • Невозможно сгруппировать данные (например, обернуть все элементы данных внутри одного div)
  • Невозможно установить фиксированную высоту

Мой вопрос заключается в том, как заставить разрывы столбцов внутри макета оболочки flex-flow: column?

.grid {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
.grid .head {
  width: 25%;
  background: orange;
  border-bottom: thin dotted;
}
.grid .data {
  width: 25%;
  background: yellow;
  border-bottom: thin dotted;
}
/* my attempt to solve this */
.grid {
  height: 76px;
}
<div class="grid">
  <div class="head">Column 1 (3 items)</div>
  <div class="data">item 1-1</div>
  <div class="data">item 1-2</div>
  <div class="data">item 1-3</div>
  <div class="head">Column 2 (4 items)</div>
  <div class="data">item 2-1</div>
  <div class="data">item 2-2</div>
  <div class="data">item 2-3</div>
  <div class="data">item 2-4</div>
  <div class="head">Column 3 (2 items)</div>
  <div class="data">item 3-1</div>
  <div class="data">item 3-2</div>
  <div class="head">Column 4 (1 items)</div>
  <div class="data">item 4-1</div>
</div>
4b9b3361

Ответ 1

Очевидно, что правильным решением является использование свойства break-before или break-after:

Разрыв принудительно выполняется везде, где свойства CSS2.1 page-break-before/page-break-after [CSS21] или CSS3 break-before/break-after [CSS3-BREAK] указывают на разрыв фрагментации.

На момент написания большинство браузеров неправильно реализовали свойства *-break-* или не реализовали их вообще. Рассмотрим этот ответ раньше времени.

Следующая демоверсия работает в:

  • FF33

.grid {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}
.grid .head {
  width: 25%;
  background: orange;
  border-bottom: thin dotted;
}
.grid .data {
  width: 25%;
  background: yellow;
  border-bottom: thin dotted;
}
/* force column breaks */
.grid .head:nth-child(n + 2) {
  page-break-before: always; /* FF33 */
}
<div class="grid">
  <div class="head">Column 1 (3 items)</div>
  <div class="data">item 1-1</div>
  <div class="data">item 1-2</div>
  <div class="data">item 1-3</div>
  <div class="head">Column 2 (4 items)</div>
  <div class="data">item 2-1</div>
  <div class="data">item 2-2</div>
  <div class="data">item 2-3</div>
  <div class="data">item 2-4</div>
  <div class="head">Column 3 (2 items)</div>
  <div class="data">item 3-1</div>
  <div class="data">item 3-2</div>
  <div class="head">Column 4 (1 items)</div>
  <div class="data">item 4-1</div>
</div>

Ответ 2

Я не думаю, что есть способ сделать это с помощью flexbox, однако, если мы используем column-count, мы можем воспользоваться преимуществами:

'break-before,' break-after ', break-inside

В частности:

Мы можем установить break-before: column; на каждый элемент "head", где значение столбца означает:

Всегда принудительно перерыва столбца перед сгенерированным полем.

(аналогично, если бы мы использовали break- после: столбец, это заставит разорвать столбцы после сгенерированного окна)

NB: Поддержка браузера в настоящее время ограничена IE (!!)

FIDDLE (только для IE)

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

Ответ 3

Если вы можете динамически добавлять div перед каждой головой (кроме первой), это может быть возможно. Кредиты идут Тобиасу Бьеррому Алину. Протестировано на Chrome, Firefox, Safari и IE11.

.container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  height: 200px;
}

.item {
  background-color: #A2CBFA;
  border: 1px solid #4390E1;
  margin: 2px;
}

.break {
  flex-basis: 100%;
}
<div class="container">
  <div class="item">item 1</div>
  <div class="item">item 2</div>
  <div class="break"></div>
  <div class="item">item 3</div>
  <div class="item">item 4</div>
  <div class="item">item 5</div>
  <div class="break"></div>
  <div class="item">item 6</div>
  <div class="break"></div>
  <div class="item">item 7</div>
  <div class="item">item 8</div>
</div>