user13286
user13286

Reputation: 3085

How can I make flex items expand to the available width up to 4 elements per row?

I have a flexbox container and I would like the items within the container to use up as much width as they need in order to fill the entire width of the row. But I would also like to make it so that only 4 items can be in each row. So if there was 1 element in the container, I want it to take 100% width, 2 elements 50% each, etc. up to 4 elements at 25%. How can I do this?

.container {
  width:800px;
  margin:0 auto;
  display:flex;
  flex-wrap:wrap;
}

.container > .item {
  min-width:25%;
  margin-left:10px;
}
  .container > .item:first-child, .container > .item:nth-child(5n) {
  margin-left:0;
  }
<h4>3 elements - should be 33% width each</h4>
<div class="container">
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50">
</div>
</div>

<h4>5 elements - should be 25% width each and wrap</h4>
<div class="container">
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50">
</div>
<div class="item"><img src="http://placehold.it/250x50">
</div>
<div class="item"><img src="http://placehold.it/250x50">
</div>
</div>

Upvotes: 4

Views: 1303

Answers (2)

Michael Benjamin
Michael Benjamin

Reputation: 372264

Use the flex-grow property to consume free space (when there are less than four items), and the flex-basis property to ensure a maximum of four items per row.

.container {
  width: 800px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex: 1 0 20%;     /* fifth item will wrap because of left margin;
                        lots of leftover free space for margins */
  overflow: auto;    /* intrinsic size of 4 images is wider than container */
}

.item + .item {
  margin-left: 10px; /* applies only to items preceded by an item */
}

.item:nth-child(5n) {
  margin-left: 0;
}
<h4>3 elements - should be 33% width each</h4>
<div class="container">
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
</div>

<h4>5 elements - should be 25% width each and wrap</h4>
<div class="container">
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
</div>

Upvotes: 3

Hans Felix Ramos
Hans Felix Ramos

Reputation: 4434

You can use flex rule, and make width inside each flex to 100% :

.container {
  width: 800px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}

.container > .item {
  flex: 1 0 25%;
}

.container>.item img{
  width: 100%;
}
<h4>3 elements - should be 33% width each</h4>
<div class="container">
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50">
  </div>
</div>

<h4>5 elements - should be 25% width each and wrap</h4>
<div class="container">
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
  <div class="item"><img src="http://placehold.it/250x50"></div>
</div>

Upvotes: 2

Related Questions