Change the Column Order in a CSS Grid

Change the column order in a css grid

Grid Layout provides multiple methods for re-arranging grid items. I've listed four below.

  1. The grid-template-areas property
  2. Line-based placement
  3. The order property
  4. The dense function of the grid-auto-flow property. (Possibly the simplest, easiest and most robust solution for this type of layout, as it works for any number of grid items.)

Here's the original layout:

grid-container {

display: grid;

grid-template-columns: 15% 1fr 25%;

grid-auto-rows: 50px; /* for demo */

grid-gap: 10px;

}

/* non-essential decorative styles */

grid-item {

border: 1px solid gray;

background-color: lightgreen;

display: flex;

align-items: center;

justify-content: center;

}

grid-item:nth-child(2) {

background-color: orange;

}
<grid-container>

<grid-item>1</grid-item>

<grid-item>2</grid-item>

<grid-item>3</grid-item>

</grid-container>

Reordering items with CSS Grid

CSS Grid provides multiple methods for achieving your layout, including line-based placement, grid areas and the order property. I'll post examples of the first two below.

Line-based placement

.container {

display: grid;

grid-template-columns: 1fr 1fr;

grid-template-rows: 50px;

grid-gap: .5em;

padding: .5em;

border: 1px solid black;

}

@media ( max-width: 600px) {

.container {

grid-template-columns: 1fr;

grid-template-rows: 50px 50px;

}

#b {

grid-row: 1;

}

}

/* non-essential decorative styles */

#a { background-color: lightgreen; }

#b { background-color: orange; }

#a, #b { display: flex; align-items: center; justify-content: center; font-size: 1.5em; }
<div class="container">

<div id="a">A</div>

<div id="b">B</div>

</div>

CSS Grid: Switch two specific columns order

You can use order property with a flex or grid container. If you don't want to use order, you can play with grid-column and grid-row like below.

.row {
display: grid;
grid-template-columns: 1fr;
}

@media screen and (min-width: 1200px) {
.row {
grid-template-columns: 1fr 1fr
}
.row>div:nth-child(3) {
grid-column: 2 / 3;
}
.row>div:nth-child(4) {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
}

.row div {
border: 1px solid black
}
<div class="row">
<div>[IMG]</div>
<div>Text</div>
<div style="background: red">[IMG]</div>
<div style="background: yellow">Text</div>
<div>[IMG]</div>
<div>Text</div>
</div>

Change order of items in CSS Grid

The only addition that is needed to the given code is to set the first two elements to order 1, the featured element to order 2 and all the others to order 3.

CSS grid will place the third li alongside the two with order 1 when there is room otherwise it will go below the featured li.

* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: Arial, Geneva, Helvetica, sans-serif;
color: #515C62;
}

ul {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(max(200px, 100% / 3), 1fr));
grid-auto-flow: dense;
}

li {
background: #CACAC7;
padding: 5px;
height: 50px;
margin: 10px;
list-style-type: none;
color: white;
font-weight: bold;
font-size: 2em;
text-align: center;
order: 3;
}

#feature {
background-color: #FF5916;
color: white;
grid-column: 1 / -1;
order: 2;
}

li:nth-child(1),
li:nth-child(2) {
order: 1;
}
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li id="feature">4 (feature)</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
</body>

How do I re-order columns with CSS grid?

Just make it grid-auto-flow: column;

.grid {
display: grid;
grid-auto-flow: column;
grid-gap: 1px;
}

.grid>* {
background: orange;
}

.fruit {
grid-column: 3/4;
}

.color {
grid-column: 2/3;
}

.cost {
grid-column: 1/2;
}
<div class="grid">
<div class="fruit">Apple</div>
<div class="color">Red</div>
<div class="cost">$1.00</div>
<div class="fruit">Banana</div>
<div class="color">Yellow</div>
<div class="cost">$1.20</div>
<div class="fruit">Lime</div>
<div class="color">Green</div>
<div class="cost">$0.75</div>
</div>

Reverse order of columns in CSS Grid Layout

As the Grid auto-placement algorithm lays out items in the container, it uses next available empty cells (source).

In your source code the A element comes before the B element:

<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, then uses the next available space to place B.

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.

http://www.w3.org/TR/css3-grid-layout/#common-uses-auto-placement


grid-auto-flow: dense

One solution to this problem (as you have noted) is to override the default grid-auto-flow: row with grid-auto-flow: dense.

With grid-auto-flow: dense, the Grid auto-placement algorithm will look to back-fill unoccupied cells with items that fit.

#container {
display: grid;
grid-template-columns: 240px 1fr;
grid-auto-flow: dense; /* NEW */
}

7.7. Automatic Placement: the grid-auto-flow
property

Grid items that aren’t explicitly placed are automatically placed into
an unoccupied space in the grid container by the auto-placement
algorithm.

grid-auto-flow controls how the auto-placement algorithm works,
specifying exactly how auto-placed items get flowed into the grid.

dense

If specified, the auto-placement algorithm uses a “dense” packing
algorithm, which attempts to fill in holes earlier in the grid if
smaller items come up later. This may cause items to appear
out-of-order, when doing so would fill in holes left by larger items.

#container {

display: grid;

grid-template-columns: 240px 1fr;

grid-auto-flow: dense; /* NEW */

}

.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>

Change column order of layout for mobile and desktop

display: contents;

With your actual markup, one of the soution would be to use display: contents; on .main div.

These elements don't produce a specific box by themselves. They are replaced by their pseudo-box and their child boxes. Please note that the CSS Display Level 3 spec defines how the contents value should affect "unusual elements" — elements that aren’t rendered purely by CSS box concepts such as replaced elements.

Source: MDN.

Two caveats:

  • It might remove the content from the accessibility tree
  • It's not supported by IE

Snippet as follows :

.wrapper {
display: flex;
flex-flow: row wrap;
}

.wrapper > * {
flex: 1 100%;
margin: 20px 0;
}

.main {
margin-right: 20px;
margin-left: 20px;
display: contents;

.inner-content {
background: yellow;
padding: 10px;

&.first {
margin-bottom: 20px;
}
}
}

.aside-1,
.aside-2 {
background: yellow;
padding: 10px;
}

.last {
order: 2;
}

.aside-2, .last {
width: 100%;
margin: 20px 0;
}

@media all and (min-width: 600px) {
.aside {
flex: 1 0 0;
}
}

@media all and (min-width: 800px) {
.main {
flex: 1 0px;
display: block;
}

.aside-1 {
order: 1;
}

.main {
order: 2;
}

.aside-2 {
order: 3;
}

.last {
width: auto;
}
}
<div class="wrapper">
<div class="aside aside-1">
<h2>container 1</h2>
</div>
<div class="main">
<div class="inner-content first">
<h2>container 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque id fermentum erat, cursus viverra risus. Cras sodales risus justo, in pretium eros pretium ut.</p>
</div>
<div class="inner-content last">
<h2>container 4</h2>
</div>
</div>
<div class="aside aside-2">
<h2>container 3</h2>
</div>
</div>


Related Topics



Leave a reply



Submit