I have a container set up via flexbox. I'd like to equally distribute each of the tiles inside the container but keep them at a fixed width of 220px.
I've come close using flex-grow
and setting a min-width: 220px
, but it obviously has computationally resized the tiles in order to fill the container.
I've also set up some media queries so that the tiles stack on certain breakpoints.
With my current styling is it possible to keep these tiles at 220px without them stretching? Can this be done via flexbox? Is there an alternative that's just as good as flexbox?
Fiddle
.container {
border: 1px solid red;
display: flex;
flex-wrap: wrap;
margin: 0 auto;
max-width: 2000px;
}
.tiles {
border: 1px solid black;
margin: 0 15px 30px 15px;
flex-grow: 1;
padding: 0;
height: 220px;
min-width: 220px;
}
@media screen and (max-width: 1140px) {
.container {
max-width: 850px;
}
}
@media screen and (max-width: 2040px) {
.container {
max-width: 1750px;
}
}
@media screen and (max-width: 1790px) {
.container {
max-width: 1500px;
}
}
@media screen and (max-width: 1540px) {
.container {
max-width: 1250px;
}
}
@media screen and (max-width: 1290px) {
.container {
max-width: 1000px;
}
}
@media screen and (max-width: 1040px) {
.container {
max-width: 750px;
}
}
@media screen and (max-width: 790px) {
.container {
max-width: 500px;
}
}
<div class="container">
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
<div class="tiles"></div>
</div>
A flexbox item can be set to a fixed width by setting 3 CSS properties — flex-basis, flex-grow & flex-shrink. flex-basis : This property specifies the initial length of the flex item. flex-grow : This property specifies how much the flex item will grow relative to the rest of the flex items.
Of course CSS grid and flexbox can work together in a layout. You can use flexbox inside CSS grid and vice versa. For instance, you could use flexbox to center an element like a button both vertically and horizontally within a particular grid cell (since centering with other CSS methods is … tricky).
Will CSS Grid make Flexbox Obsolete in the Future? Absolutely not. In fact, that's what this article was about. CSS grid and Flexbox, both are designed to solve a different set of problems.
If you are using flexbox and find yourself disabling some of the flexibility, you probably need to use CSS Grid Layout. An example would be if you are setting a percentage width on a flex item to make it line up with other items in a row above. In that case, a grid is likely to be a better choice.
I'd like to equally distribute each of the tiles inside the container but keep them at a fixed width of 220px.
With my current styling is it possible to keep these tiles at 220px without them stretching?
Can this be done via flexbox?
Yes, and yes.
Instead of using flex-grow
and min-width
on the tiles, use the flex
property.
So, instead of:
.tiles {
flex-grow: 1;
min-width: 220px;
}
Try this:
.tiles {
flex: 0 0 220px; /* don't grow, don't shrink, stay at 220px width */
}
The flex
property is shorthand for flex-grow
, flex-shrink
, flex-basis
.
The flex-grow
property controls how a flex item will grow relative to other flex items in the container when extra space is distributed. By setting the value to 0
, it doesn't grow at all from the initial main size (defined by flex-basis
).
The flex-shrink
property controls how a flex item will shrink relative to other flex items when they overflow the container. By setting the value to 0
, it doesn't shrink at all from the initial main size (defined by flex-basis
).
The flex-basis
property sets the initial main size of a flex item.
I've also setup some media queries so that the tiles stack on certain breakpoints.
By using the flex
property, as specified above, along with flex-wrap
, which you already have in your code, you may not need media queries. Consider scrapping them.
At this point, you may have your layout: DEMO
OR
You may be at a common sticking point: When flex items wrap, the container does not recalculate its width to shrink-wrap the fewer columns, resulting in a large area of whitespace on the right.
For more details and a possible workaround see my answer here: Flexbox Limitation & Challenge
UPDATE
After a few clarifications and revisions were made in the comments, the solution was found:
HTML
<ul id="content">
<li class="box"></li>
<li class="box"></li>
<li class="box"></li>
...
...
...
</ul>
CSS
*
{
margin:0;padding:0;
}
#content {
display: flex;
flex-wrap: wrap;
list-style: none;
margin:0 auto;
}
.box {
flex: 0 0 90px;
height: 90px;
margin: 5px;
background-color: blue;
}
@media (min-width: 200px) {
#content {
width: 200px;
}
}
@media (min-width: 300px) {
#content {
width: 300px;
}
}
@media (min-width: 400px) {
#content {
width: 400px;
}
}
@media (min-width: 500px) {
#content {
width: 500px;
}
}
@media (min-width: 600px) {
#content {
width: 600px;
}
}
@media (min-width: 700px) {
#content {
width: 700px;
}
}
@media (min-width: 800px) {
#content {
width: 800px;
}
}
@media (min-width: 900px) {
#content {
width: 900px;
}
}
@media (min-width: 1000px) {
#content {
width: 1000px;
}
}
@media (min-width: 1100px) {
#content {
width: 1100px;
}
}
DEMO
So flexbox has the ability to grow and shrink, which you can turn off (you can read a little more about that here, I find this a nice, quick flexbox guide). Shorthand for defining flex-grow
, flex-shrink
, and flex-basis
all at once is flex: 0 0 auto
, the zeros meaning that the box won't grow or shrink, but remain the same size you defined previously. I modified your jsfiddle to show how it works:
FIDDLE
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