Why are flex items not wrapping?
I am attempting to make multiple rows of squares (3 per line) which have the same height.
I have written some HTML and CSS for this but the boxes all go on the same line.
Here's what I have so far:
#list-wrapper {
display: flex;
width: 100%;
}
#list-wrapper div {
width: 33.33%;
}
#list-wrapper div img {
flex: 1;
}
<div id="list-wrapper">
<div>
<img src="images/1.png" alt="image one" />
</div>
<div>
<img src="images/2.png" alt="image two" />
</div>
<div>
<img src="images/1.png" alt="image one" />
</div>
<div>
<img src="images/2.png" alt="image two" />
</div>
<div>
<img src="images/1.png" alt="image one" />
</div>
<div>
<img src="images/2.png" alt="image two" />
</div>
</div>
When I load the page with this all boxes appear but they are all on one line going over the parent div's 100% width.
Solution 1:
An initial setting of a flex container is flex-wrap: nowrap
.
This means that when you create a flex container (by applying display: flex
or display: inline-flex
to an element) all child elements ("flex items") are confined to a single line.
To enable flex items to wrap use flex-wrap: wrap
.
Here are a few examples of how flex properties work:
A simple flex container with various flex items containing an image:
#list-wrapper {
display: flex;
border: 1px solid black;
}
#list-wrapper div {}
#list-wrapper div img {
height: 150px;
width: 150px;
}
<div id="list-wrapper">
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
</div>
Note that only one flex property has been declared: display: flex
. This establishes the flex container. The following behaviors are by default:
flex-wrap: nowrap
flex-direction: row
justify-content: flex-start
To allow the items to wrap, add flex-wrap: wrap
:
#list-wrapper {
display: flex;
flex-wrap: wrap; /* NEW */
border: 1px solid black;
}
#list-wrapper div { }
#list-wrapper div img {
height: 150px;
width: 150px;
}
<div id="list-wrapper">
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
</div>
To allow only three items per row, use the flex
property:
#list-wrapper {
display: flex;
flex-wrap: wrap;
border: 1px solid black;
}
#list-wrapper div {
margin: 10px;
flex: 1 1 calc(33.33% - 20px); /* flex-grow, flex-shrink,
flex-basis: (width - margin) */
}
#list-wrapper div img {
height: 150px;
width: 150px;
}
<div id="list-wrapper">
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
</div>
Also, all flex items have equal height by default (align-items: stretch
).
#list-wrapper {
display: flex;
flex-wrap: wrap;
border: 1px solid black;
}
#list-wrapper div {
margin: 10px;
flex: 1 1 calc(33.33% - 30px);
border: 1px solid #ccc;
background-color: lightgreen;
text-align: center;
}
#list-wrapper div img {
height: 150px;
width: 150px;
}
<div id="list-wrapper">
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
</div>
The stretch is more noticeable if you restore flex-wrap: nowrap
and give the container a height:
#list-wrapper {
display: flex;
/* flex-wrap: wrap; */
border: 1px solid black;
height: 600px;
}
#list-wrapper div {
margin: 10px;
flex: 1 1 calc(33.33% - 30px);
border: 1px solid #ccc;
background-color: lightgreen;
text-align: center;
}
#list-wrapper div img {
height: 150px;
width: 150px;
}
<div id="list-wrapper">
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
<div><img src="http://i.imgur.com/60PVLis.png" alt=""></div>
</div>
Solution 2:
If you are using flexbox and want the content to wrap, you must specify flex-wrap: wrap
. By default flex items don't wrap.
Your code here is doing nothing because the parent of #list-wrapper div img
is not display: flex
. You need to move this to #list-wrapper div
:
#list-wrapper div img {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
}
To have the images be three-across, you should specify flex-basis: 33.33333%
.
Change your CSS to this and it will work:
#list-wrapper {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
width: 100%;
flex-wrap: wrap;
}
#list-wrapper div {
flex: 0 0 33.333%;
}
JS Fiddle: https://jsfiddle.net/f47prnnt/1/