16

I have this at the moment:

.container {
  background: gray;
  width: 600px;
  display: flex;
  flex-flow: row wrap;
  position: relative;
}
.item {
  background: blue;
  width: auto;
  height: auto;
  margin: 4px;
  flex: 1;
  flex-basis: 20%;
}
<div class="container">
  <div class="item">A</div>
  <div class="item">B</div>
  <div class="item">C</div>
  <div class="item">D</div>
  <div class="item">E</div>
  <div class="item">F</div>
  <div class="item">G</div>
</div>

What I'm trying to do is have 5 items per row in a flexbox. Currently they don't appear because they don't have a set width/height, which leads me to my next question. Is it possible to auto-resize the items in order for 5 of them to fit per row?

How would I do this?

Thanks!

Al Foиce ѫ
  • 4,195
  • 12
  • 39
  • 49
user6828106
  • 245
  • 1
  • 2
  • 6

4 Answers4

49

You are right in giving a flex-basis: 20% but you have to adjust for the 4px margin on each flex item for it to wrap properly.


Equal Width Flex items in the last row

Use flex: 0 1 calc(20% - 8px) - this means the item won't grow beyond 20% of width (adjusting for margin) and can shrink based on the container width. See demo below:

.container {
  background: gray;
  width: 600px;
  height: 200px; /* height given for illustration */
  display: flex;
  flex-flow: row wrap;
  position: relative;
}

.item {
  background: blue;
  margin: 4px;
  flex: 0 1 calc(20% - 8px); /* <-- adjusting for margin */
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Another approach is a bit hacky - you can keep flex-grow set to one and flex-basis: calc(20% - 4px) using flex: 1 1 calc(20% - 4px), and use a pseudo element that fills the remaining space:

.container {
  background: gray;
  width: 600px;
  height: 200px; /* height given for illustration */
  display: flex;
  flex-flow: row wrap;
  position: relative;
}

.item {
  background: blue;
  margin: 4px;
  flex: 1 1 calc(20% - 8px); /* <-- adjusting for margin */
}

.container:after {
  content: '';
  display: block;
  flex: 999; /* grow by a large number */
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

If you don't have the n item per row requirement then you can refer this:


Flex items in last row expands to fill the available space

If in a row you have less than 5 items and you want them to fill in the remaining space use flex: 1 1 calc(20% - 8px) (note that flex-grow is set to 1 here so that the flex items in the last rows expand to fill the remaining space):

.container {
  background: gray;
  width: 600px;
  height: 200px;  /* height given for illustration */
  display: flex;
  flex-flow: row wrap;
  position: relative;
}

.item {
  background: blue;
  margin: 4px;
  flex: 1 1 calc(20% - 8px);  /* <-- adjusting for margin */
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
Community
  • 1
  • 1
kukkuz
  • 41,512
  • 6
  • 59
  • 95
6

try below css for five items in each row.

.container {
  background: gray none repeat scroll 0 0;
  display: flex;
  flex-flow: row wrap;
  position: relative;
  width: auto;
}

.item {
  background: blue none repeat scroll 0 0;
  flex: 1 1 18%;
  height: auto;
  margin: 4px;
  padding: 20px 0;
  width: auto;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
Jainam
  • 2,590
  • 1
  • 9
  • 18
  • Any way to keep the second row items the same width/height as the first row's items? – user6828106 Sep 15 '16 at 06:58
  • just noticed.. in this answer it will not work as `flex-basis` is 18%... you will have some space after the fifth div at the end of the row :( – kukkuz Sep 15 '16 at 07:13
3

I'm using this on a WordPress project, where I have to list articles by categories, nested in columns. I just wrote some css for the responsive layout, so as you decrease the browser width, there are less elements in a row.

.container {
  margin: 20px auto;
  width: 80%;
  min-height: 100px;
  display: flex;
  flex-flow: row wrap;
}

.item {
  margin: 10px;
  flex: 1 1 calc(20% - 20px);
  background-color: lightgreen;
}

@media screen and (max-width: 1200px) {
  .item {
    flex: 1 1 calc(25% - 20px)
  }
}

@media screen and (max-width: 900px) {
  .item {
    flex: 1 1 calc(33% - 20px)
  }
}

@media screen and (max-width: 750px) {
  .item {
    flex: 1 1 calc(50% - 20px)
  }
}

@media screen and (max-width: 550px) {
  .item {
    flex: 1 1 calc(100% - 20px)
  }
}
<div class="container">
  <div class="item"><a>Link1</a></div>
  <div class="item"><a>Link1</a></br><a>Link2</a></div>
  <div class="item"><a>Link1</a></br><a>Link2</a></br><a>Link3</a></div>
  <div class="item"><a>Link1</a></br><a>Link2</a></br><a>Link3</a></br><a>Link4</a></div>
  <div class="item"><a>Link1</a></br><a>Link2</a></br><a>Link3</a></br><a>Link4</a></br><a>Link5</a></div>
  <div class="item"><a>Link1</a></br><a>Link2</a></br><a>Link3</a></br><a>Link4</a></br><a>Link5</a></br><a>Link6</a></div>
</div>
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Zsiga
  • 31
  • 2
1

Here is a possible solution: https://jsfiddle.net/9f955jk2/3/ You have to be aware of margins or paddings, that's why I setted the width to 18% You can set them to 20% (100%/5 items per row) if you will remove all the margins and paddings. Also don't forget that border will also take some space. The container should have 100%, otherwise you have to divide the width by 5 and specify it in pixel for each item and not in %

 .container {
      width:100%;
    }
vadber
  • 239
  • 4
  • 16