问题
As you can see from the Snippet below (View as Fiddle), an absolutely positioned, columnar flexbox won't expand to fit its children.
In Chrome, for example, it will only be as wide as the widest child element and as tall as the shortest column.
Can anyone suggest a solution without using any additional markup?
Edit: The number of items in the list will be dynamic, as will the text in each item. I need to break to a new column after a set number of items.
*{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:
A flex box with the position:absolute;
is no longer considered a flex box hence your current issue.
You must use predefined widths and heights if your going to use position:absolute;
.
See here for w3c on flexboxes http://www.w3.org/TR/css3-flexbox/#flex-items
"flex items themselves are flex-level boxes, not block-level boxes: they participate in their container’s flex formatting context, not in a block formatting context."
By changing to position:absolute;
you force the flex container to be a block element (this happens to all elements with position:absolute;
), thus eliminating the flexible nature of it and also because its contents are not block elements they are flex children they can only effect a flex level container not a block one .
The Jquery Solution
Right so there is a way to do it with jquery.
This might not be what you wanted because it's not CSS only but it does work.
What I'am doing here is getting the width of the container at its original width.
Then getting the max width of every 6th element (because that's when your row's break to form a new column).
Then counting the total number columns there is and use that to multiply the max width of each column by the number of column's and then finally add it all together to get the desired width of your container.
feel free to take away and add new column's to test it all out.
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:
The reason your child elements won't fit in the flex-container is that you set a max-height
on container .
But what is happening in your original sample is strange (specially the child elements getting unstacked from column );
it looks like the flex-items are not being able to recognize the container borders while the flexbox is trying to stuff them in anyway (even changing flex-direction:column
);
the only thing that actually makes sense is the maximum width of the widest element.
here's a snippet without 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>
EDIT
I don't know what your desired output is but a typical flexbox implementation could be something like this:
ul{
background:#090;
display:flex;
flex-flow:column wrap;
list-style:none;
padding:5px;
/*position:absolute;*/
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;
/* 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>
来源:https://stackoverflow.com/questions/29536119/absolutely-positioned-flexbox-doesnt-expand-to-fit-contents