patstuart
patstuart

Reputation: 1988

Force minimum items per row with Flexbox

Using CSS flex, is it possible to force an equal number of items per row?

I am able to get the items to wrap, but not to have the same number per row (Fiddle).

.container {
    display: flex;
    flex-flow: row wrap;
    position: relative;
}

.container > div {
    padding: 49px;
    flex: 1;
    box-sizing: border-box;
}

Here is a diagram of what I'm trying to accomplish:

enter image description here

Upvotes: 9

Views: 8292

Answers (2)

vals
vals

Reputation: 64244

May be you are looking for quantity queries, where you change the style depending on how many items there are on a list

a list apart article

.container {
  display: flex;
  flex-flow: row wrap;
  border: solid 1px green;
}
.container > div {
  flex: 1 0;
  background-color: lightgreen;
  height: 30px;
  margin: 5px;
}


.item:first-child:nth-last-child(3),
.item:first-child:nth-last-child(3) ~ .item {
  flex-basis: 30%;  
}

.item:first-child:nth-last-child(4),
.item:first-child:nth-last-child(4) ~ .item {
  flex-basis: 40%;  
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Upvotes: 7

Michael Benjamin
Michael Benjamin

Reputation: 371699

You can use flex-wrap to control wrapping and media queries to adjust the size of flex items:

.container {
  display: flex;
  flex-flow: row nowrap; /* disable browser-controlled wrapping */
}
.container > div {
  padding: 49px 0;
  text-align: center;
  flex: 1;
  box-sizing: border-box;
}
input[type=button] {
  background: red;
}
@media ( max-width: 700px) {
  .container { flex-wrap: wrap; }
  .container > div { flex-basis: 33.33%; }
}
@media ( max-width: 400px) {
   .container > div { flex-basis: 50%; }
}
<div class="container">
  <div><input type="button" value="Button 1"></div>
  <div><input type="button" value="Button 2"></div>
  <div><input type="button" value="Button 3"></div>
  <div><input type="button" value="Button 4"></div>
  <div><input type="button" value="Button 5"></div>
  <div><input type="button" value="Button 6"></div>
</div>

revised fiddle

In the example above, at a certain breakpoint (screen width 700px, in this case), flex-wrap: wrap is enabled and each flex item becomes 33% wide, forcing three items per row.

At a smaller breakpoint, flex-basis adjusts to 50%, allowing only two items per row.

Upvotes: 4

Related Questions