wanaryytel
wanaryytel

Reputation: 3482

How to make a CSS grid wrap automatically if the templates are set for columns and rows?

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?

Upvotes: 3

Views: 10666

Answers (3)

Ilya Streltsyn
Ilya Streltsyn

Reputation: 13536

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>

Upvotes: 4

vals
vals

Reputation: 64174

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>

Upvotes: 2

Tanner Babcock
Tanner Babcock

Reputation: 3350

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>

Upvotes: 0

Related Questions