Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the column order in a css grid

Tags:

html

css

css-grid

I am playing around with CSS grids.

When I view it on a desktop size (min-width: 769px) I have a single row with 3 columns - something like this:

--------------------------------------------- |   col 1     |         col 2       | col 3 | |             |                     |       | --------------------------------------------- 

Can I with css-grid move the columns around so I can do something like this on a mobile layout:

--------------------------------------------- |     col 1             |      col 3        | |                       |                   | --------------------------------------------- |                     col 2                 | --------------------------------------------- 

I know I span cells with something like this:

.content{   grid-column: 1 / span2; } 

But I want to change the order of the columns. Can I do that without a pre-processor?

Here is my current grid class:

.my-grid {    display:grid;    grid-template-columns: 15% 1fr 25% ;    grid-template-rows: 1fr; /* for as many rows as you need */    grid-gap: 10px;    border: 2px solid #222;    box-sizing: border-box; } 
like image 890
jwknz Avatar asked Jul 28 '17 07:07

jwknz


People also ask

How do I change order of columns in CSS?

Use grid-row-start , grid-row-end , grid-column-start , grid-column-end , or their shorthands, grid-row and grid-column , to set a grid item's size and location in the grid.

How do I change my position in CSS grid?

Move grid items If you completely want to relocate an item into another grid cell/area I recommend you update the grid creation code. Moving around grid items is simple. Just use the margin , the transform , or the position:relative; properties. See below how the items are moved using those properties.

How do you arrange a grid element in CSS?

With CSS grid layout, the grid itself within its container as well as grid items can be positioned with the following 6 properties: justify-items , align-items , justify-content , align-content , justify-self , and align-self .

How do you set the order of grid layout?

The order property can be used to specify the order in which different items should be placed inside a grid. By default, the items are placed in the order in which they appear in the DOM. For example, if item A is above item B in the actual source document, it will also be placed in the grid before item B.


1 Answers

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>

jsFiddle demo 1


1. The grid-template-areas property

The grid-template-areas property allows you to arrange your layout using ASCII visual art.

Place the grid area names (which are defined for each element) in the position where you want them to appear.

grid-container {    display: grid;    grid-template-columns: 15% 1fr 25%;    grid-auto-rows: 50px; /* for demo */    grid-gap: 10px;    grid-template-areas: "column-1 column-2 column-3";  }    grid-item:nth-child(1) { grid-area: column-1; }  grid-item:nth-child(2) { grid-area: column-2; }  grid-item:nth-child(3) { grid-area: column-3; }    @media ( max-width: 500px ) {      grid-container {           grid-template-columns: 1fr 1fr;           grid-template-areas: " column-1 column-3 "                                " column-2 column-2 ";     }  }    /* 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>

jsFiddle demo 2

From the specification:

7.3. Named Areas: the grid-template-areas property

This property specifies named grid areas, which are not associated with any particular grid item, but can be referenced from the grid-placement properties.

The syntax of the grid-template-areas property also provides a visualization of the structure of the grid, making the overall layout of the grid container easier to understand.

All strings must have the same number of columns, or else the declaration is invalid.

If a named grid area spans multiple grid cells, but those cells do not form a single filled-in rectangle, the declaration is invalid.

Note: Non-rectangular or disconnected regions may be permitted in a future version of this module.


2. Line-based Placement

Use grid-row-start, grid-row-end, grid-column-start, grid-column-end, or their shorthands, grid-row and grid-column, to set a grid item's size and location in the grid.

grid-container {    display: grid;    grid-template-columns: 15% 1fr 25%;    grid-auto-rows: 50px; /* for demo */    grid-gap: 10px;  }    @media ( max-width: 500px ) {      grid-container         { grid-template-columns: 1fr 1fr;  }    grid-item:nth-child(1) { grid-row: 1 / 2; grid-column: 1 / 2; }    grid-item:nth-child(2) { grid-row: 2 / 3; grid-column: 1 / 3; }    grid-item:nth-child(3) { grid-row: 1 / 2; grid-column: 2 / 3; }  }    /* 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>

jsFiddle demo 3

From the specification:

8.3. Line-based Placement: the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties


3. The order property

The order property in Grid Layout does the same as in Flex Layout.

grid-container {    display: grid;    grid-template-columns: 15% 1fr 25%;    grid-auto-rows: 50px; /* for demo */    grid-gap: 10px;  }    @media ( max-width: 500px ) {      grid-container         { grid-template-columns: 1fr 1fr;  }    grid-item:nth-child(1) { order: 1; }    grid-item:nth-child(2) { order: 3; grid-column: 1 / 3; }    grid-item:nth-child(3) { order: 2; }  }    /* 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>

jsFiddle demo 3

From the specification:

6.3. Reordered Grid Items: the order property


4. The dense function of the grid-auto-flow property

This solution is possibly the simplest, easiest and most robust of all presented here, as it works for any number of grid items.

Although this solution doesn't provide any major advantage over the previous three in the layout described in the question, which consists of only three grid items, it offers huge benefits when the number of grid items is higher or dynamically-generated.

This question and the solutions above address this:

01  03 02  02 

But let's say we need this:

01  03 02  02  04  06 05  05  07  09 08  08  10  12 11  11  and so on... 

Using grid-template-areas, line-based placement and order, the solution would require a lot of hard-coding (if we knew the number of total items) and maybe CSS custom properties and/or JavaScript (if the items were generated dynamically).

The dense function of CSS Grid, however, can handle both scenarios simply and easily.

By applying grid-auto-flow: dense to the container, each third item will backfill the empty cell created as a result of consecutive ordering.

grid-container {    display: grid;    grid-template-columns: 15% 1fr 25%;    grid-auto-rows: 50px;    grid-gap: 10px;  }    @media (max-width: 500px) {    grid-container {      grid-template-columns: 1fr 1fr;      grid-auto-flow: dense;     /* KEY RULE; deactive to see what happens without it;                                    defaults to "sparse" (consecutive ordering) value */    }    grid-item:nth-child(3n + 2) {      grid-column: 1 / 3;    }  }    /* 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(-n + 3)                    { background-color: aqua; }  grid-item:nth-child(n + 4):nth-child(-n + 6)   { background-color: lightgreen; }  grid-item:nth-child(n + 7):nth-child(-n + 9)   { background-color: orange; }  grid-item:nth-child(n + 10):nth-child(-n + 12) { background-color: lightgray; }
<grid-container>    <grid-item>1</grid-item>    <grid-item>2</grid-item>    <grid-item>3</grid-item>    <grid-item>4</grid-item>    <grid-item>5</grid-item>    <grid-item>6</grid-item>    <grid-item>7</grid-item>    <grid-item>8</grid-item>    <grid-item>9</grid-item>    <grid-item>10</grid-item>    <grid-item>11</grid-item>    <grid-item>12</grid-item>  </grid-container>

jsFiddle demo 4

From the specification:

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

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.

If omitted, a “sparse” algorithm is used, where the placement algorithm only ever moves “forward” in the grid when placing items, never backtracking to fill holes.

like image 91
Michael Benjamin Avatar answered Oct 15 '22 15:10

Michael Benjamin