WoJ
WoJ

Reputation: 29987

Does the order of elements define their place in a CSS grid?

The following code works as expected: the cells are filled with colors between defined lines

#grid {
  display: grid;
  height: 100px;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 100px;
}

#item1 {
  background-color: lime;
}

#item2 {
  background-color: yellow;
  grid-column: 2/4;
}

#item3 {
  background-color: blue;
  grid-column: 4/7;
}
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
</div>

I then tried to swap the last two elements (yellow and blue), by swapping the grid-column entries:

#grid {
  display: grid;
  height: 100px;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 100px;
}

#item1 {
  background-color: lime;
}

#item2 {
  background-color: yellow;
  grid-column: 4/7;
}

#item3 {
  background-color: blue;
  grid-column: 2/4;
}
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
</div>

item3 is not correctly displayed. I suppose that this is because item2 has been rendered further in the grid and the earlier element cannot be rendered anymore (wild guessing).

I am lost at how the order of the elements in the HTML is influenced by the placement of elements in the CSS, as explained in the documentation? Shouldn't the order in the HTML be insignificant?

Upvotes: 3

Views: 109

Answers (1)

Marvin
Marvin

Reputation: 10092

The items are inserted one by one into the grid in the order of appearance in the html and according to their specified placement. The placement algorithm does not try to fill any previous gaps.

Note: By default, the auto-placement algorithm looks linearly through the grid without backtracking; if it has to skip some empty spaces to place a larger item, it will not return to fill those spaces. To change this behavior, specify the dense keyword in grid-auto-flow.

One item is placed into the second row

#grid {
  display: grid;
  height: 300px;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 100px;
}

#item1 {
  background-color: lime;
}

#item2 {
  background-color: yellow;
  grid-column: 4/7;
}

#item3 {
  background-color: blue;
  grid-column: 2/4;
}

#item4 {
  background-color: grey;
  grid-column: 5/6;
}

#item5 {
  background-color: orange;
  grid-column: 1/7;
}
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
  <div id="item4"></div>
  <div id="item5"></div>
</div>

In your example you could either make use of the grid-auto-flow property and set it to dense as suggested by the documentation:

#grid {
  display: grid;
  height: 100px;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 100px;
  grid-auto-flow: dense;
}

#item1 {
  background-color: lime;
}

#item2 {
  background-color: yellow;
  grid-column: 4/7;
}

#item3 {
  background-color: blue;
  grid-column: 2/4;
}
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
</div>

or you could make use of the order property to get the wished result:

#grid {
  display: grid;
  height: 100px;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 100px;
}

#item1 {
  background-color: lime;
}

#item2 {
  background-color: yellow;
  grid-column: 4/7;
  order: 3;
}

#item3 {
  background-color: blue;
  grid-column: 2/4;
  order: 2;
}
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
</div>

or, as suggested by GCyrillus, force the third item to be placed in the first row by using the grid-row property:

#grid {
  display: grid;
  height: 100px;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: 100px;
}

#item1 {
  background-color: lime;
}

#item2 {
  background-color: yellow;
  grid-column: 4/7;
}

#item3 {
  background-color: blue;
  grid-column: 2/4;
  grid-row: 1;
}
<div id="grid">
  <div id="item1"></div>
  <div id="item2"></div>
  <div id="item3"></div>
</div>

Upvotes: 5

Related Questions