5

I want to show 4 items in 1st row as it is, but only 3 in second line, and then 4 in 3rd line and 3 in 4th line and so on...

I have achieved this by nth-child but code was too much and not flexible and expandable.

Is it possible by flex? or grid?

* {
  box-sizing: border-box;
}

.grid-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.grid-wrapper .grid-item {
  width: 25%;
  text-align: center;
  padding: 5px;
}

p {
  background: #ddd;
  padding: 15px;
}
<div class="grid-wrapper">
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>


</div>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
Atul Rajput
  • 4,073
  • 2
  • 12
  • 24
  • 1
    All items must be the same size? Will something like this work for you? https://jsfiddle.net/jxt5cm7u/2/ – Michael Benjamin Apr 26 '19 at 13:23
  • So... where do you want to define how many items per line are shown? The `nth-child` syntax allows you to do that programmatically. Otherwise, you could use a `data-` attribute in the HTML and use an attribute selector in CSS to key off of that. – Heretic Monkey Apr 26 '19 at 14:05

2 Answers2

6

You only need to consider one rule like below:

 /*7 = 4 (1st row) + 3 (2nd row) and 5 = 1st element in 2nd row (4 + 1)*/
.grid-wrapper .grid-item:nth-child(7n + 5) {
  width: calc(100%/3);
  flex-grow:0;
}

The trick is to make one element bigger to trigger the wrap then rely on flex-grow to fill the space.

Full code

* {
  box-sizing: border-box;
}

.grid-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.grid-wrapper .grid-item {
  width: 25%;
  text-align: center;
  padding: 5px;
  flex-grow: 1;
}

.grid-wrapper .grid-item:nth-child(7n + 5) {
  width: calc(100%/3);
  flex-grow:0;
}

p {
  background: #ddd;
  padding: 15px;
}
<div class="grid-wrapper">
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div><div class="grid-item">
    <p>Grid Item</p>
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
2

Is it possible by flex? or grid?

Here is a solution using grid which is easier to construct:

  • consider a 12-column grid layout using grid-template-columns: repeat(12, 1fr),

  • place each grid-item into 4 columns by using grid-column: span 3,

  • 7 grid-items are repeating in a pattern; which means every even row has 3 items with nth-child indices 7n, 7n - 1 and 7n - 2.

See demo below:

* {
  box-sizing: border-box;
}

.grid-wrapper {
  display: grid; /* grid container */
  grid-template-columns: repeat(12, 1fr); /* 12-column layout */
}

.grid-wrapper .grid-item {
  text-align: center;
  padding: 5px;
  grid-column: span 3; /* 4 items in a row */
}

.grid-wrapper .grid-item:nth-child(7n - 2),
.grid-wrapper .grid-item:nth-child(7n - 1),
.grid-wrapper .grid-item:nth-child(7n) { /* even row */
  grid-column: span 4; /* 3 items in the even row */
}

p {
  background: #ddd;
  padding: 15px;
}
<div class="grid-wrapper">
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>


</div>

Flexbox solution

And I'd use just about the same nth-child logic in the case of a flexbox and the only change in your code would be the below:

.grid-wrapper .grid-item:nth-child(7n - 2),
.grid-wrapper .grid-item:nth-child(7n - 1),
.grid-wrapper .grid-item:nth-child(7n) { /* even row */
  width: 33.33%;
}

See demo below:

* {
  box-sizing: border-box;
}

.grid-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.grid-wrapper .grid-item {
  width: 25%;
  text-align: center;
  padding: 5px;
}

p {
  background: #ddd;
  padding: 15px;
}

/* ADDED THESE */
.grid-wrapper .grid-item:nth-child(7n - 2),
.grid-wrapper .grid-item:nth-child(7n - 1),
.grid-wrapper .grid-item:nth-child(7n) { /* even row */
  width: 33.33%;
}
<div class="grid-wrapper">
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>
  <div class="grid-item">
    <p>Grid Item</p>
  </div>


</div>

On a separate note, if you interested in having n items in a row with flexboxes, the below answers may give you more information:

Community
  • 1
  • 1
kukkuz
  • 41,512
  • 6
  • 59
  • 95