10

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>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Carl Edwards
  • 13,826
  • 11
  • 57
  • 119
  • Do you also need the *tiles* to be always in the center? – Stickers Jan 09 '16 at 02:01
  • have you tried simply setting the `width` property of your `.tiles`? – Jason Jan 09 '16 at 02:06
  • See this [updated fiddle](https://jsfiddle.net/3ud9fkw5/4/), I guess you don't need those media queries. – Stickers Jan 09 '16 at 02:07
  • @Pangloss Sorry I seemed to misworded my pervious comment. I basically wanted the grid to work as so (without using `float`: http://jsfiddle.net/danield770/EBncj/6/. Via: http://stackoverflow.com/a/21245751/3046413 – Carl Edwards Jan 09 '16 at 02:21
  • Got you! OK see this post - http://stackoverflow.com/q/33192745/483779 I actually offered a bounty of 200 rep for it a while ago, still no better solutions so far, even with flexbox. – Stickers Jan 09 '16 at 02:23
  • Awesome! Thanks so much for referring me to this solution. I have one question though: Is it possible for the `.inner` div to align left, span the width of its parent (100%) and function in the same manner as before? – Carl Edwards Jan 09 '16 at 02:33

3 Answers3

11

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

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

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

alyssums
  • 139
  • 8
1

After reading the comments on Michael_B answer, I believe that what is missing is a justify-content: center ...

.container {
  display: flex;
  flex-wrap: wrap;
  margin: 0 auto;
  max-width: 2000px;
  justify-content: center;
}

.tiles {
  border: 1px solid black;
  margin: 0 15px 30px 15px;
  flex: 0 0 220px;
  padding: 0;
  height: 220px;
}

.filler {
  border: 1px solid transparent;
  margin: 0 15px 0px 15px;
  flex: 0 0 220px;
  padding: 0;
  height: 0px;
  }
<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 class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
  <div class="filler"></div>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138
  • The problem I'm finding with `justify-content` is that the odd remaining tiles with center (as they should) vs. aligning left. – Carl Edwards Jan 09 '16 at 22:47
  • Adding extra elements to the HTML would be ok ? – vals Jan 09 '16 at 22:52
  • Well..the tiles will be generated dynamically so I won't be able to determine how many/few there are in the container. – Carl Edwards Jan 09 '16 at 23:18
  • You don't need to. You only need to add a number high enough for the worst case. See the example with 10 fillers – vals Jan 10 '16 at 08:28