3

I have 12 children divs in my .wrapper element that I'd like to stack next to each other. The number 12 is actually dynamic so I have no idea how many children I'll have. Right now my grid layout looks like this:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto;
  grid-auto-flow: column dense;
  grid-gap: 10px;
}

This is fine until the grid should start wrapping the elements (the layout is full, the grid is 3x2 which holds 6 elements). The seventh, eigth and all of the rest are stacked next to the first six, although I would want them to be in a new line with the same template (so essentially my grid would become 2x(3x2)).

The explanation probably doesn't make too much sense on its own, check out the Codepen as well.

How do I make the elements after the sixth one wrap into a new line?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
wanaryytel
  • 3,352
  • 2
  • 18
  • 26
  • In the default `grid-auto-flow: row` direction, you use `repeat`, `minmax` and `auto-fill` / `auto-fit`. https://codepen.io/anon/pen/jKgONG – Michael Benjamin Jul 06 '18 at 22:21
  • With `grid-auto-flow: column`, there are obstacles: https://stackoverflow.com/q/44092529/3597276 – Michael Benjamin Jul 06 '18 at 22:24
  • @Michael_B Nope, this makes One and Two stack next to each other instead of under each other. The first column should be One, Two, Seven, Eight. – wanaryytel Jul 06 '18 at 22:26

3 Answers3

4

You can use auto flow to form grid (like @vals's answer suggests) and then set the pattern in which order it should be populated via set of :nth-child() rules:

.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}

.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: row dense;
  grid-gap: 10px;
}

.wrapper > :nth-child(6n + 1),
.wrapper > :nth-child(6n + 2) {
  grid-column: 1;
}

.wrapper > :nth-child(6n + 3),
.wrapper > :nth-child(6n + 4) {
  grid-column: 2;
}

.wrapper > :nth-child(6n + 5),
.wrapper > :nth-child(6n + 6) {
  grid-column: 3;
}
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
  
  <div>Six</div>
  <div>Seven</div>
  <div>Eight</div>
  <div>Nine</div>
  <div>Ten</div>
  <div>Eleven</div>
  <div>Twelve</div>
  
  <div>Thirteen</div>      
  <div>Fourteen</div>      
  <div>And so on</div>
</div>
Ilya Streltsyn
  • 13,076
  • 2
  • 37
  • 57
  • This grid stuff is magical, but the solution that vals proposed and you perfected works! Thanks! I chose this as the correct answer because I needed the grid to work for n+1 elements. – wanaryytel Jul 07 '18 at 13:40
2

Use grid-auto-flow: row. And then you need to set a special rule for items 2 and 4, just setting the row will be enough.

I have removed the grid-templated-rows: auto property, it's the default, and it's not needed if you position the elements this way.

.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}

.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-flow: row dense;
  grid-gap: 10px;
}

.wrapper div:nth-child(-2n + 4) {
  grid-row: 2;
  background-color: yellow;
}
<div class="wrapper">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
  
  <div>Six</div>
  <div>Seven</div>
  <div>Eight</div>
  <div>Nine</div>
  <div>Ten</div>
  <div>Eleven</div>
  <div>Twelve</div>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138
  • It looks that OP wants the items in each 3x2 subpattern to go in columns. If so, special rules for 2 items would be not sufficient, the `:nth-child` selectors will need to specify the whole pattern, like ```.wrapper > :nth-child(6n + 1), .wrapper > :nth-child(6n + 2) { grid-column: 1; } .wrapper > :nth-child(6n + 3), .wrapper > :nth-child(6n + 4) { grid-column: 2; } .wrapper > :nth-child(6n + 5), .wrapper > :nth-child(6n + 6) { grid-column: 3; }``` – Ilya Streltsyn Jul 07 '18 at 09:35
0

This should work for you. I changed the value of grid-auto-flow from column dense to row dense.

* {box-sizing: border-box;}

.wrapper {
    border: 2px solid #f76707;
    border-radius: 5px;
    background-color: #fff4e6;
}

.wrapper > div {
    border: 2px solid #ffa94d;
    border-radius: 5px;
    background-color: #ffd8a8;
    padding: 1em;
    color: #d9480f;
}
.wrapper {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: auto auto;
    grid-auto-flow: row dense;
    grid-gap: 10px;
}
<div class="wrapper">
    <div>One</div>
    <div>Two</div>
    <div>Three</div>
    <div>Four</div>
    <div>Five</div>
    
    <div>Six</div>
    <div>Seven</div>
    <div>Eight</div>
    <div>Nine</div>
    <div>Ten</div>
    <div>Eleven</div>
    <div>Twelve</div>
</div>
Tanner Babcock
  • 3,232
  • 6
  • 21
  • 23
  • This still stacks One and Two next to each other, not underneath each other. The first column should be One, Two, Seven, Eight, etc, etc... – wanaryytel Jul 06 '18 at 22:27