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 {_x000D_
display: flex;_x000D_
flex-wrap: wrap;_x000D_
}_x000D_
_x000D_
.child {_x000D_
flex: 1 0 21%; /* explanation below */_x000D_
margin: 5px;_x000D_
height: 100px;_x000D_
background-color: blue;_x000D_
}
_x000D_
<div class="parent">_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
<div class="child"></div>_x000D_
</div>
_x000D_
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.