Change the column order in a css grid
Grid Layout provides multiple methods for re-arranging grid items. I've listed four below.
- The
grid-template-areas
property - Line-based placement
- The
order
property - The
dense
function of thegrid-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 ingrid-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
propertyGrid 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
Possible to Style the CSS3 Resize Function
Cross-Browser Embedded Font in Svg Image
How to Apply a Border Only Inside a Table
How to Use External Font in CSS
iOS Not Respecting Z-Index with -Webkit-Overflow-Scrolling
Html/CSS How to Prevent Highlighting Text from Spanning Entire Width of Page in Google Chrome
Remove Value Attribute of Input Element Using CSS Only
Delay HTML5 :Invalid Pseudo-Class Until the First Event
How to Set a Microdata Image Property, Without Letting the Browser Download the Image
Center Image in Div Horizontally
Is It a Bug? Margins of P Element Go Outside the Containig Div
Three Horizontal Stripes in CSS