DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!
The grid-area
CSS property is a shorthand that specifies the location and the size of a grid item in a grid layout by setting the value of grid-row-start
, grid-column-start
, grid-row-end
and grid-column-end
in one declaration.
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}
.grid-item:nth-child(2) {
grid-area: 2 / 4 / 4 / 6;
/* is equivalent to: */
grid-row-start: 2;
grid-column-start: 4;
grid-row-end: 4;
grid-column-end: 6;
}
Because of CSS Grid’s default auto-placement behavior, the second grid item in this example would normally be placed in the second column of the grid’s first row. But since we declared grid-area
and set it to align the grid item’s starting and ending edges with our desired grid lines, the item moved to the second row and fourth column and spanned two tracks in both directions to meet the correct ending grid lines.
Constituent properties
As mentioned, the grid-area
property is a shorthand that combines four properties:
grid-column-start
.element { grid-column-start: 3; }
grid-column-end
.element { grid-column-end: 4; }
grid-row-start
.element { grid-row-start: 2; }
grid-row-end
.element { grid-row-end: 3; }
Syntax
grid-area: <grid-line> [ / <grid-line> ]{0,3}
Full definition
<grid-line> =
auto |
<custom-ident> |
[ [ <integer [−∞,−1]> | <integer [1,∞]> ] && <custom-ident>? ] |
[ span && [ <integer [1,∞]> || <custom-ident> ] ]
- Initial value:
auto
- Applies to: grid items and absolutely-positioned boxes whose containing block is a grid container
- Inherited: no
- Computed value: as specified for its longhand properties
- Animation type: discrete
This property can take up to four values separated by a forward slash (/
).
Four values
If four <grid-line>
values are specified:
- The first value sets the
grid-row-start
property. - The second value sets the
grid-column-start
property. - The third value sets the
grid-row-end
property. - The fourth value sets the
grid-column-end
property.
.grid-item {
grid-area: 2 / 4 / 3 / 6;
/* is equivalent to: */
grid-row-start: 2;
grid-column-start: 4;
grid-row-end: 3;
grid-column-end: 6;
}
Three values
When three values are specified — grid-column-end
is omitted. If grid-column-start
is a <custom-ident>
, grid-column-end
is set to that <custom-ident>
; otherwise, it is set to auto
.
- The first value sets the
grid-row-start
property. - The second value sets the
grid-column-start
property.- It also sets the
grid-column-end
property if the value is a<custom-ident>
. - Otherwise,
grid-column-end
is set toauto
.
- It also sets the
- The third value sets the
grid-row-end
property.
/* <custom-ident> */
.grid-item {
grid-area: 2 / area / 4;
/* is equivalent to */
grid-row-start: 2;
grid-column-start: area;
grid-row-end: 4;
grid-column-end: area;
}
/* <grid-line> */
.grid-item {
grid-area: 2 / 4 / 3;
/* is equivalent to: */
grid-row-start: 2;
grid-column-start: 4;
grid-row-end: 3;
grid-column-end: auto;
}
Two values
When two values are specified, grid-row-end
and grid-column-end
are omitted. If the grid-row-start
and grid-column-start
values are a <custom-ident>
, then grid-row-end
and grid-column-end
are set to that <custom-ident>
; otherwise, they are set to auto
.
- The first value sets the
grid-row-start
property.- It also sets the
grid-row-end
property if the value is a<custom-ident>
. - Otherwise,
grid-row-end
is set toauto
.
- It also sets the
- The second value sets the
grid-column-start
property.- It also sets the
grid-column-end
property if the value is a<custom-ident>
. - Otherwise,
grid-column-end
is set toauto
.
- It also sets the
/* <custom-ident> */
.grid-item {
grid-area: area / 4;
/* is equivalent to */
grid-row-start: area;
grid-column-start: 4;
grid-row-end: area;
grid-column-end: auto;
}
/* another <custom-ident> example */
.grid-item {
grid-area: area / another-area;
/* is equivalent to */
grid-row-start: area;
grid-column-start: another-area;
grid-row-end: area;
grid-column-end: another-area;
}
/* <grid-line> */
.grid-item {
grid-area: 2 / 4;
/* is equivalent to */
grid-row-start: 2;
grid-column-start: 4;
grid-row-end: auto;
grid-column-end: auto;
}
Single value
When one value is specified, if grid-row-start
is a <custom-ident>
, all four constituent properties are set to that value. Otherwise, they are set to auto
.
/* <custom-ident> */
.grid-item {
grid-area: area;
/* is equivalent to */
grid-row-start: area;
grid-column-start: area;
grid-row-end: area;
grid-column-end: area;
}
/* <grid-line> */
.grid-item {
grid-area: 2;
/* is equivalent to */
grid-row-start: 2;
grid-column-start: auto;
grid-row-end: auto;
grid-column-end: auto;
}
Making sense of this syntax
The different scenarios based on the number of values — not to mention the <custom-ident>
cases — might seem complicated and odd at first. But if you think about it a bit, it all makes sense.
Take the following grid item as an example:
.grid-item {
grid-area: 2 / 4 / 3;
}
Here, grid-column-end
is omitted (because this is a three-value syntax) and the grid-column-start
is set to 4
. The grid-column-end
property cannot be also 4
because the starting and ending edge of the grid item will point at the same line. The browser doesn’t align the starting edge to 4
and spans the grid item to one column as the default behavior. That’s why when an edge doesn’t have a value, it is set to auto
— just in case its other edge is pointing to a grid line with a numeric value.
Now, what if the grid-column-start
value is set to a name instead? For example, x
instead of 4
:
.grid-item {
grid-area: 2 / x / 3;
}
The x
value can be the name of a grid line or a grid area. If there is a grid line named x
, then grid-column-end
is set to the x
too but since both column edges of the grid item point to the same grid line — x
—the browser’s default behavior again is to act as if grid-column-end
is set to auto
and the grid item spans one column.
On the other hand, if there is a grid area named x
, then grid-column-start
is set to the starting edge of that grid area and the grid-column-end
is set to its ending edge.
It’s much easier to grok all that when you see it in code:
.grid-item {
grid-area: 2 / x / 3;
/* is equivalent to */
grid-row-start: 2;
grid-column-start: x-start;
grid-row-end: 3;
grid-column-end: x-end;
}
Values
/* Keyword value */
grid-area: auto;
/* <custom-ident> value */
grid-area: my-area;
grid-area: main-start / sidebar-start;
grid-area: main-start / sidebar-start / footer-start / main-end;
grid-area: line1 / line2 / line3 / line4;
/* <integer> + <custom-ident> values */
grid-area: 3;
grid-area: 2 / -3;
grid-area: main 2;
grid-area: 2 a / 4 b / 2 x;
/* span + <integer> + <custom-ident> values */
grid-area: span 3;
grid-area: 1 / 3 / span 2 / 5;
grid-area: 1 / span myline;
grid-area: 2 / span gridline 3;
/* Global values */
grid-area: inherit;
grid-area: initial; /* same as `auto` */
grid-area: revert;
grid-area: revert-layer;
grid-area: unset;
auto
This is the default value. It indicates the default span (1
) and auto-placement behavior, which means the grid item is automatically placed in the next available empty grid cell.
<custom-ident>
This syntax allows you to either use an integer to refer to a numbered grid line or a string to refer to a named grid line or a named grid area. In other words, you can specify a grid line by its numerical index or name to the edges of a grid item.
Positioning items by line numbers
There are two grid lines before and after each grid track with a numerical index assigned to them automatically, starting from number one.
In the first example of this article, we used this syntax to refer to the second and fourth row grid lines by their index (2
and 4
) to align the starting and the ending edge of the grid item with the starting and the ending edge of the second and third rows. Also, we refer to the fourth and sixth column grid lines to align the starting and the ending edges of the grid item with the starting and the ending edges of the fourth and the fifth columns.
.grid-item:nth-child(2) {
grid-area: 2 / 4 / 4 / 6;
}
Note that you can also use a negative number to refer to a grid line, but it counts starting from the ending edge of the grid. The following code points to the same grid lines in the previous example, but counting in reverse:
.grid-item:nth-child(2) {
grid-column: -4 / -4 / -2 / -2; /* same as: grid-area: 2 / 4 / 4 / 6; */
}
Notice the negative integers have been assigned to our grid:
Positioning items by line names
You can assign a custom name to a grid line using the grid-template-columns
and grid-template-rows
line-based placement grid properties to refer to that line by its name.
Let’s go back to our example and name the column and row track lines like this:
.grid {
display: grid;
grid-template-rows: 100px [row2] 100px 100px [row4] 100px;
grid-template-columns: 1fr 1fr 1fr [fourth] 1fr 1fr [second-to-last] 1fr;
}
We can refer to the third and the fifth line by our custom names — row2
, row4
, fourth
and second-to-last
— instead of their index values — 2
, 4
, 4
, and 6
, respectively:
.grid-item:nth-child(2) {
grid-area: row2 / fourth / row4 / second-to-last; /* same as index numbers 2 / 4 / 4 / 6 */
}
Note that the <custom-ident>
cannot take the span
value. span
is a reserved keyword for grid placement properties (e.g. grid-column: 1 / span 2
).
Positioning items by grid areas
When defining grid areas using the grid-template-areas
property, you get implicit line names for free based on the name of the areas. For instance, a grid area with the name content
generates a line named content-start
before it and one named content-end
after it. You can refer to these lines to set the position of a grid item.
.grid-item:nth-child(2) {
grid-area: content-start / content-start / content-end / content-end;
}
Alternately, you can refer to the area’s name to position an item at the starting and ending line of the content
named area:
.grid-item:nth-child(2) {
grid-area: content;
}
Here is a full example:
<body>
<header></header>
<main></main>
<aside></aside>
<footer></footer>
</body>
body {
display: grid;
gap: 16px;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: min-content 1fr min-content;
grid-template-areas:
"header header header"
"content content sidebar"
"footer footer footer";
}
header {
grid-area: header;
}
main {
grid-area: content;
}
aside {
grid-area: sidebar;
}
footer {
grid-area: footer;
}
This sets the position of the grid elements where we want them in our grid.
<integer> && <custom-ident>?
This flavor of syntax allows you to position grid items by grid lines when there are repeated names. If there are grid lines with the same name, this syntax helps specify which of those lines you are referring to.
.grid {
display: grid;
grid-template-columns: [a] 1fr [b] 1fr [b] 1fr [b] 1fr [b];
grid-template-rows: [x] 1fr [y] 1fr [y] 1fr [y] 1fr [y];
/*
Using repeat() function also gives you repeated named grid line, for example:
grid-template-columns: repeat(3, [b] 1fr);
*/
}
Let’s assume you want to choose the third line among the row tracks, but that line has the same name as the second, fourth, and last grid line — all of them are called y
. Since the second line named y
is the third grid line, you can use 2
to select it as the starting point. The same way of counting applies to the other values of grid-area
in the following example:
.grid-item:nth-child(2) {
grid-area: 2 y / 3 b / 4 y / 4 b;
/* This is equivalent to: */
grid-row-start: 2 y;
grid-column-start: 3 b;
grid-row-end: 4 y;
grid-column-end: 4 b;
}
Note that the order of the values doesn’t matter. We could have also written the previous code like this:
.grid-item:nth-child(2) {
grid-area: y 2 / b 3 / y 4 / b 4;
}
Like the previous syntax, you can use a negative integer to count the grid lines starting from the ending edge of the grid too. In our example, if we want to refer to the same lines, we can count starting from the ending edge of our grid and write it like this:
.grid-item:nth-child(2) {
grid-area: -3 y / -2 b / -1 y / -1 b;
}
Note that the integer value cannot be zero.
span && [ <integer> || <custom-ident> ]
This syntax allows a grid item to span across the grid tracks. It can be specified in three different ways.
Note that if the integer is not specified anywhere in this syntax — the default value is 1
.
span <integer>
Using the span
keyword followed by an integer indicates the number of tracks a grid item spans from a specific grid line. For example, if we want a grid item to span three row tracks and two column tracks towards its starting edge, we can apply the following value:
.grid-item:nth-child(2) {
grid-area: span 3 / span 2;
/* This is equivalent to */
grid-row-start: span 3;
grid-column-start: span 2;
grid-row-end: auto;
grid-column-end: auto;
}
span <custom-ident>
It’s also possible to combine the span
keyword with the name of a grid line to make the grid item expand until it reaches that specified grid line.
.grid-item:nth-child(3) {
grid-area: auto / 3 / auto / span lastline;
}
Since the starting line of the grid item is known (3
), we can span the item until it hits a column grid line named lastline
.
span <custom-ident> <integer>
If the specified grid line name is assigned to more than one grid line — in other words, if we have repeated named grid lines — we need to say which ones we want to target. To do that, we can add an integer to our value specifying which grid line we are referring to.
Take the following grid as an example:
.grid-container {
display: grid;
grid-template-columns: [y] 1fr [x] 1fr [x] 1fr [y] 1fr [x] 1fr [x];
}
.grid-item:nth-child(3) {
grid-area: 2 / 2 / 4 / span x 2;
}
We set the starting line of the grid item to the second column line. Then we want it to span forward until it hits a grid line named x
. And since we want it to be the second x
grid line, we wind up with span x 2
.
As a result, our grid item spans from the second line, as illustrated below. The first line that it hits is the first one, x
, followed by y
, and finally, it hits the desired second line, named x
.
This syntax is helpful when you want to span a grid item towards a grid line using its name. But beware aware that there is more than one grid line with the same name using this method, so we add an integer to say we want the N
of that grid line.
See grid-row-start
, grid-row-end
, grid-column-start
and the grid-column-end
for more information and examples of the syntax for each constituent property.
Examples
Let’s poke at s few examples to demonstration how grid-area
is used to place items on a grid.
Creating a multi-layer banner
Let’s say this graphic is handed to you from your design team:
They also provide another version to show you that it was designed on a grid:
Let’s first set up our HTML:
<figure>
<img class="back" src="back.jpg" alt="Please">
<img class="middle" src="middle.jpg" alt="fill your alt">
<img class="front" src="front.jpg" alt="properly">
<figcaption>Freedom is the oxygen of the soul...</figcaption>
</figure>
There are fourteen columns and nine rows in the design. We can write that out like this:
figure {
display: grid;
grid-template-columns: repeat(14, 50px);
grid-template-rows: repeat(9, 50px);
}
We need to place all those child <img>
elements into their right grid areas. And for that we use the grid-area
property:
.back {
grid-area: 1 / 3 / -2 / -1;
}
.middle {
grid-area: 2 / 1 / 7 / 9;
}
.front {
grid-area: 4 / 4 / -1 / -3;
}
figcaption {
grid-area: -3 / -4 / -1 / -1;
}
You can see the result in the following image:
Take a look at the demo to check more details about this example:
Stacking grid items
When positioning items across the grid, we can stack or overlap them on top of each other. This gives us the ability to sometimes use CSS Grid as an alternative to absolute positioning. For instance, we can put a caption layer on top of an image without using the position
property as demonstrated below:
<figure>
<img src="image.png" alt="how dare you leave alt empty?">
<figcaption>The caption of our image</figcaption>
</figure>
figure {
display: grid;
}
img,
figcaption {
grid-area: 1 / 1 / -1 / -1;
}
Here’s what we get:
By default, grid items stack in the source order, but you can control their level using the z-index
property. In the following example, we overlap some items and we use the z-index
property to bring the second item to the highest level in the stacking context:
.item:nth-child(2) {
grid-area: 2 / 2 / 4 / 4;
z-index: 1;
}
Accessibility
One thing to note when using the grid placement properties is the issue caused by rearranging the items. When you change the position of an item, only the visual order of the grid items changes, and that order might not be the same as the original document order. This may cause a very bad experience for someone tabbing through the document on a keyboard or listening to a screen reader that reads the content in the same order as the HTML.
So, avoid changing the order of grid items when the HTML order of the elements matters. For example, it can be good for a random image gallery but perhaps not so much for your form inputs.
However, at the time of this writing, there is a proposal to tackle this issue that will hopefully resolve this concern in the future.
Demo
You can change the value of grid-area
property in the demo to see what happens to the third grid item:
Browser support
More information
Related tricks!
Breaking Out with CSS Grid Explained
Exploring CSS Grid’s Implicit Grid and Auto-Placement Powers
Positioning Overlay Content with CSS Grid
Simple Named Grid Areas
Using Grid Named Areas to Visualize (and Reference) Your Layout
Code as Documentation: New Strategies with CSS Grid
Related
display
.element { display: inline-block; }
grid-auto-columns
.element { grid-auto-columns: minmax(100px, 200px); }
grid-auto-flow
.element { grid-auto-flow: dense; }
grid-auto-rows
.element { grid-auto-rows: minmax(1fr, 500px) 3fr; }
grid-column
.element { grid-column: 3 / 5; }
grid-column-end
.element { grid-column-end: 4; }
grid-column-start
.element { grid-column-start: 3; }
grid-row
.element { grid-row: 2 / 4; }
grid-row-end
.element { grid-row-end: 3; }
grid-row-start
.element { grid-row-start: 2; }
grid-template-areas
.element { grid-template-areas: "header header" "sidebar main"; }
grid-template-columns
.element { grid-template-columns: 300px 1fr; }
grid-template-rows
.element { grid-template-rows: minmax(auto, 1fr) 3fr; }