grid-area

Avatar of Mojtaba Seyedi
Mojtaba Seyedi on

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

Setting the location and the size of the second grid item using the grid-area CSS property.

Constituent properties

As mentioned, the grid-area property is a shorthand that combines four properties:

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 specifiedgrid-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 to auto.
  • 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 to auto.
  • 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 to auto.
/* <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.

Demonstrating the index of row and column grid tracks.

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:

Placing the second grid item into the second and third rows and fourth and fifth columns using grid-area CSS property.
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.

Placing the grid items into grid areas by their names using the grid-area CSS property.

<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;
}
The grid item spans two columns and three rows using the grid-area CSS property.
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.

The grid item spans across the grid until it hits the specified grid line named lastline using the grid-area CSS property.
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.

Setting the position of a grid item from the second column line to the second x named line using the grid-area property.

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:

Three overlapping images with a blockquote positioned in the bottom-right corner.

They also provide another version to show you that it was designed on a grid:

Showing teh grid lines for a design as an overlay.

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:

Showing a grid layout with an overlay revealing the layout's grid lines.

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;
}
Bringing the second grid item to the top of the stack using the z-index property.

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