I am using flexbox to create a nice grid of tiles that automatically wraps when the tiles don't fit on one row.
I use justify-content: space-between
so that the tiles stick to the left and right sides of the parent container, and any remaining space is only distributed "in the middle" but not to the left and right.
Any other justify
option also puts space to the left and right of the outer two flex items.
The problem is that when a row doesn't have the same number of tiles as the previous row, I'd like the last row's tiles to align to the left. Can this be done using only flex properties?
Current outcome:
▀ ▀ ▀
▀ ▀
Desired outcome:
▀ ▀ ▀
▀ ▀
HTML
<div class="browser">
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
</div>
CSS
.browser {
width: 700px;
display:flex;
justify-content: space-between;
padding-bottom:100px;
flex-wrap:wrap;
border:1px solid red;
}
.case {
flex: 0 0 200px;
background-color:#ccc;
height:100px;
border:1px solid blue;
margin-bottom:10px;
}
Codepen
The flex-wrap CSS property sets whether flex items are forced onto one line or can wrap onto multiple lines. If wrapping is allowed, it sets the direction that lines are stacked.
nowrap: The default value of wrap-flex is nowrap. It is used to specify that the item has no wrap. It makes item wrap in single lines.
For 3 items per row, add on the flex items: flex-basis: 33.333333% You can also use the flex 's shorthand like the following: flex: 0 0 33.333333% => which also means flex-basis: 33.333333% .
A solution is to add a hidden element using pseudo-element so you will have 6 elements and keep the layout you need.
.browser {
width: 700px;
display: flex;
justify-content: space-between;
padding-bottom: 100px;
flex-wrap: wrap;
border: 1px solid red;
}
.case {
flex: 0 0 200px;
background-color: #ccc;
height: 100px;
border: 1px solid blue;
margin-bottom: 10px;
}
.browser:after {
content:"";
flex: 0 0 200px;
}
<div class="browser">
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
<div @click='projectClicked' class="case">
<h3>Project</h3>
</div>
</div>
CSS
It's pretty annoying, but you can't use flexbox for that.
The better way is to go with CSS grid instead, and apply
/* for space-around style */
.fixed-grid--around{
grid-template-columns: repeat(auto-fill, minmax(150px,1fr));
justify-items: center;
}
/* for space-between style*/
.fixed-grid--between{
grid-template-columns: repeat(auto-fit, 150px);
justify-content: space-between;
}
/* both should run fixed width elements equal to the declared in the container */
.grid-element{
width: 150px;
}
By setting the grid columns minimum width to their elements width and the max column width to 1 fr we can get them to evenly distribute the space around them. For space-between style, autofit and space-between does the trick.
So it adds columns to fill the container, evenly distributes the space between them until another column can be added, and wraps as needed. Just what we always hoped for flexbox to do.
A pen I made before exploring the issue:
If you're gonna use this, make sure to add some fallback for browsers that don't support grid. might be floats, inline-blocks, flex, or whatever. CSS Grid is really good at overriding the fallbacks, so it's fairly easy to apply.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With