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>
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>
From the specification:
7.3. Named Areas: the
grid-template-areas
propertyThis 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>
From the specification:
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>
From the specification:
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>
From the specification:
§7.7. Automatic Placement: the
grid-auto-flow
propertydense
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.