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

Как видно из нижеприведенного фрагмента (View as Fiddle), абсолютно позиционированный столбчатый flexbox не будет расширяться, чтобы соответствовать его детей.

В Chrome, например, он будет только шириной, чем самый широкий дочерний элемент и такой же высокий, как самый короткий столбец.

Может ли кто-нибудь предложить решение без какой-либо дополнительной разметки?

Изменить: Количество элементов в списке будет динамическим, как и текст в каждом элементе. Мне нужно разбить новый столбец после определенного количества элементов.

*{box-sizing:border-box;}
ul{
    background:#090;
    display:flex;
    flex-flow:column wrap;
    left:0;
    list-style:none;
    max-height:202px;
    padding:5px;
    position:absolute;
    top:0;
}
li{
    background:rgba(255,0,0,.75);
    color:#fff;
    flex:1 0 30px;
    font-family:arial;
    line-height:30px;
    max-height:30px;
    margin:1px;
    padding:0 2px;
    min-width:100px;
}
<ul>
    <li>Line 0</li>
    <li>Line 1</li>
    <li>Line 2</li>
    <li>Line 3</li>
    <li>Line 4</li>
    <li>Line 5</li>
    <li>Line 6</li>
    <li>Line 7</li>
    <li>Line 8 is a little bit longer</li>
</ul>

Ответы

Ответ 1

Гибкая коробка с position:absolute; больше не считается гибкой коробкой, поэтому ваша текущая проблема.

Вы должны использовать предопределенные ширины и высоты, если вы собираетесь использовать position:absolute;.


См. здесь для w3c на flexboxes http://www.w3.org/TR/css3-flexbox/#flex-items

"сами гибкие элементы представляют собой блоки уровня гибкости, а не блокировки на уровне блоков: они участвуют в контекстах форматирования контейнеров, а не в контексте форматирования блоков.

Изменяя на position:absolute;, вы вынуждаете контейнер flex быть блочным элементом (это происходит со всеми элементами с position:absolute;), тем самым устраняя его гибкий характер, а также потому, что его содержимое не является блочным элементом, из которого они гибки дети, они могут воздействовать только на контейнер уровня гибкости, а не на блок.


Решение JQuery

Итак, есть способ сделать это с помощью jquery.

Это может быть не то, что вы хотели, потому что это не CSS, но он действительно работает.

То, что я здесь делаю, это получить ширину контейнера с его первоначальной шириной.

Затем получаем максимальную ширину каждого 6-го элемента (потому что это когда ваша строка разбивается на новый столбец).

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

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

Fiddle

var count = $("ul.flex-container li:nth-child(6n)").length;

var firstWidth = Math.max.apply(null, $("ul.flex-container").map(function() {
  return $(this).outerWidth(true);
}).get());

var childWidth = Math.max.apply(null, $("ul.flex-container li:nth-child(6n+6)").map(function() {
  return $(this).outerWidth(true);
}).get());

var totalWidth = childWidth * count

$("ul.flex-container").css({
  width: firstWidth + totalWidth,
});
ul.flex-container {
  background: #090;
  display: flex;
  flex-flow: column wrap;
  list-style: none;
  max-height: 192px;
  padding: 5px;
  position: absolute;
}
ul.flex-container li {
  background: rgba(255, 0, 0, .75);
  color: #fff;
  flex: 1 0 30px;
  font-family: arial;
  line-height: 30px;
  margin: 1px;
  padding: 0 2px;
  min-width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul class="flex-container">
  <li>Line 0</li>
  <li>Line 1</li>
  <li>Line 2</li>
  <li>Line 3</li>
  <li>Line 4</li>
  <li>Line 5</li>
  <li>Line 6</li>
  <li>Line 7</li>
  <li>Line 8 is a little bit longer</li>
  <li>Line 0</li>
  <li>Line 1</li>
  <li>Line 2</li>
  <li>Line 3</li>
  <li>Line 4</li>
  <li>Line 5</li>
  <li>Line 6</li>
  <li>Line 7</li>
  <li>Line 8 is a little bit longer</li>
</ul>

Ответ 2

Причина, по которой ваши дочерние элементы не будут помещаться в контейнер flex, заключается в том, что вы устанавливаете контейнер max-height.

Но то, что происходит в вашем исходном примере, является странным (особенно дочерние элементы, которые не удаляются из столбца);

похоже, что гибкие элементы не могут распознавать границы контейнеров, а flexbox пытается наполнить их (в любом случае, меняя flex-direction:column).
единственное, что действительно имеет смысл, это максимальная ширина самого широкого элемента.

здесь фрагмент без max-width:

ul{
    background:#090;
    display:flex;
    flex-flow:column wrap;
    list-style:none;
    padding:5px;
    position:absolute; /*max-height:192px;*/
}
/*ul::after{display:table;clear:both; content:''}clearfix*/
li{
    background:rgba(255,0,0,.75);
    color:#fff;
    flex:1 0 30px;
    font-family:arial;
    line-height:30px;
    margin:1px;
    padding:0 2px;
    min-width:100px;
}
<ul>
    <li>Line 0</li>
    <li>Line 1</li>
    <li>Line 2</li>
    <li>Line 3</li>
    <li>Line 4</li>
    <li>Line 5</li>
    <li>Line 6</li>
    <li>Line 7</li>
    <li>Line 8 is a little bit longer</li>
</ul>