Since the automatic grid layout algorithm contains elements in the container, it uses the following available empty cells ( source ).
In the source code, element A is before element B:
<div id="container" class="reverse" style="width: 800px;"> <div class="a">A</div> <div class="b">B</div> </div>
Therefore, the grid container first places A and then uses the next available space to place B.
By default, the automatic placement algorithm looks linearly through the grid without backtracking; if he must skip some empty spaces to accommodate a larger element, he will not come back to fill these gaps. To change this behavior, specify the dense keyword in grid-auto-flow .
http://www.w3.org/TR/css3-grid-layout/#common-uses-auto-placement
grid-auto-flow: dense
One solution to this problem ( as you noted ) is to override the default grid-auto-flow: row using grid-auto-flow: dense .
Using grid-auto-flow: dense the automatic grid layout algorithm will look for backfilled unoccupied cells with elements that match.
#container { display: grid; grid-template-columns: 240px 1fr; grid-auto-flow: dense; }
7.7. Auto Place: grid-auto-flow Property
Grid elements that are explicitly placed are automatically placed in unallocated space in the grid container by automatically placing the algorithm.
grid-auto-flow controls how the auto-layout algorithm works, precisely indicating how automatically placed elements get into the grid.
dense
If specified, the automatic placement algorithm uses a βtightβ packing algorithm that attempts to fill holes earlier in the grid if smaller objects appear later. This can lead to the appearance of elements out of turn, when it will fill the holes left by larger objects.
#container { display: grid; grid-template-columns: 240px 1fr; grid-auto-flow: dense; } .a { background: yellow; } .b { background: blue; color: white; } #container>.a { grid-column: 1; } #container>.b { grid-column: 2; } #container.reverse>.a { grid-column: 2; } #container.reverse>.b { grid-row: 1; grid-column: 1; }
<div id="container" class="reverse" style="width: 800px;"> <div class="a">A</div> <div class="b">B</div> </div>
grid-row: 1
Another solution would be to simply define a string for the second element.
#container>.b { grid-column: 2; grid-row: 1; }
#container { display: grid; grid-template-columns: 240px 1fr; } .a { background: yellow; } .b { background: blue; color: white; } #container>.a { grid-column: 1; } #container>.b { grid-column: 2; grid-row: 1; } #container.reverse>.a { grid-column: 2; } #container.reverse>.b { grid-row: 1; grid-column: 1; }
<div id="container" class="reverse" style="width: 800px;"> <div class="a">A</div> <div class="b">B</div> </div>