Paul Alexandru
Paul Alexandru

Reputation: 25

Why are some grid items appearing out of order?

I am working on a CSS grid layout that looks something like this: https://jsfiddle.net/ftL5zw0x/23/ where I don't know how many items I will have.

The layout looks how I want it to but the problem is with the ordering. Every 6th and 7th items appear out of order, they should switch places while the layout stays unchanged. (For example items 6 and 7)

Is there any way I can achieve this through CSS alone?

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
  grid-gap: 8px;
}

.item {
  background-color: #c4c4c4;
  display: flex;
  justify-content: center;
  align-items: center;
}

div:nth-child(8n+1),
div:nth-child(8n+3), 
div:nth-child(8n+7),
div:nth-child(8n+8) {
  grid-row: span 1;
}

div:nth-child(8n+2), 
div:nth-child(8n+4),
div:nth-child(8n+5), 
div:nth-child(8n+6) {
  grid-row: span 2;
}
<div class="wrapper">
  <div class="item">item1</div>
  <div class="item">item2</div>
  <div class="item">item3</div>
  <div class="item">item4</div>
  <div class="item">item5</div>
  <div class="item">item6</div>
  <div class="item">item7</div>
  <div class="item">item8</div>
  <div class="item">item9</div>
  <div class="item">item10</div>
  <div class="item">item11</div>
  <div class="item">item12</div>
  <div class="item">item13</div>
  <div class="item">item14</div>
  <div class="item">item15</div>
  <div class="item">item16</div>
</div>

Upvotes: 1

Views: 542

Answers (2)

Michael Benjamin
Michael Benjamin

Reputation: 371221

Although every 6th and 7th item appear out of order, they are not out of order.

Look at item 5 (a span 2 item). The top half is on row 2 and the bottom half is on row 3. But it gets placed on row 2.

Same for item 6. The top half is on row 2 and the bottom half is on row 3. It gets placed on row 2, which comes before row 3, which is where item 7 gets placed.

So, 6 is placed before 7, 15 is before 16, etc., and everything is placed in order.

enter image description here

Targeting these items with CSS is not a big deal.

div:nth-child(8n+6),
div:nth-child(8n+7) {}

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
  grid-gap: 8px;

}

.item {
  background-color: #c4c4c4;
  display: flex;
  justify-content: center;
  align-items: center;
}

div:nth-child(8n+1), div:nth-child(8n+3), div:nth-child(8n+7), div:nth-child(8n+8) {
  grid-row: span 1;
}

div:nth-child(8n+2), div:nth-child(8n+4), div:nth-child(8n+5), div:nth-child(8n+6) {
  grid-row: span 2;
}

div:nth-child(8n+6),
div:nth-child(8n+7) {
    background-color: lightgreen;
}
<div class="wrapper">
  <div class="item">item1</div>
  <div class="item">item2</div>
  <div class="item">item3</div>
  <div class="item">item4</div>
  <div class="item">item5</div>
  <div class="item">item6</div>
  <div class="item">item7</div>
  <div class="item">item8</div>
  <div class="item">item9</div>
  <div class="item">item10</div>
  <div class="item">item11</div>
  <div class="item">item12</div>
  <div class="item">item13</div>
  <div class="item">item14</div>
  <div class="item">item15</div>
  <div class="item">item16</div>
</div>

But then what? Not sure there's any easy solution to the problem, but this one looks quite good.

Upvotes: 0

user7148391
user7148391

Reputation:

First change your selectors that is the 7th element that should span not the 6th

This will push the 6th element to the right following the flow of the grid that is being the position of the previous element 5th

However we can enforce the position of every 6th element because we know it's the second column.

That will make the 7th and 8th element follow the 6th element we can fix this with grid-auto-flow:row dense;

.wrapper {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 100px;
  grid-auto-flow: row dense;
  grid-gap: 8px;
}

.item {
  background-color: #c4c4c4;
  display: flex;
  justify-content: center;
  align-items: center;
}

div:nth-child(8n+1),
div:nth-child(8n+3),
div:nth-child(8n+6),
div:nth-child(8n+8) {
  grid-row: span 1;
}

div:nth-child(8n+2),
div:nth-child(8n+4),
div:nth-child(8n+5),
div:nth-child(8n+7) {
  grid-row: span 2;
}

div:nth-child(8n+6) {
  grid-column: 2;
}
<div class="wrapper">
  <div class="item">item1</div>
  <div class="item">item2</div>
  <div class="item">item3</div>
  <div class="item">item4</div>
  <div class="item">item5</div>
  <div class="item">item6</div>
  <div class="item">item7</div>
  <div class="item">item8</div>
  <div class="item">item9</div>
  <div class="item">item10</div>
  <div class="item">item11</div>
  <div class="item">item12</div>
  <div class="item">item13</div>
  <div class="item">item14</div>
  <div class="item">item15</div>
  <div class="item">item16</div>
</div>

Upvotes: 1

Related Questions