I'm using a flex box to display 8 items that will dynamically resize with my page. How do I force it to split the items into two rows? (4 per row)?
Here is a relevant snip:
(Or if you prefer jsfiddle - http://jsfiddle.net/vivmaha/oq6prk1p/2/)
You've got flex-wrap: wrap
on the container. That's good, because it overrides the default value, which is nowrap
(source). This is the reason items don't wrap to form a grid in some cases.
In this case, the main problem is flex-grow: 1
on the flex items.
The flex-grow
property doesn't actually size flex items. Its task is to distribute free space in the container (source). So no matter how small the screen size, each item will receive a proportional part of the free space on the line.
More specifically, there are eight flex items in your container. With flex-grow: 1
, each one receives 1/8 of the free space on the line. Since there's no content in your items, they can shrink to zero width and will never wrap.
The solution is to define a width on the items. Try this:
.parent {
display: flex;
flex-wrap: wrap;
}
.child {
flex: 1 0 21%; /* explanation below */
margin: 5px;
height: 100px;
background-color: blue;
}
<div class="parent">
<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>
With flex-grow: 1
defined in the flex
shorthand, there's no need for flex-basis
to be 25%, which would actually result in three items per row due to the margins.
Since flex-grow
will consume free space on the row, flex-basis
only needs to be large enough to enforce a wrap. In this case, with flex-basis: 21%
, there's plenty of space for the margins, but never enough space for a fifth item.