The grid
CSS property is a shorthand that allows you to set all the implicit and the explicit grid properties in a single declaration.
.grid-container {
display: grid;
grid: auto-flow dense / repeat(5, 150px);
}
The above example sets grid-template-columns
to repeat(5, 150px)
and grid-auto-flow
to row dense
which creates a grid container that has five explicit columns and auto-repeated rows.
Constituent properties
As mentioned, the grid
property is a shorthand that combines multiple properties. This is the list of all its sub-properties:
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-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; }
That’s a lot of properties for a single shorthand! As you might imagine, some declarations can get super complex super fast. We’ll cover the syntax and values, then get into some examples to help you use grid
them effectively.
Syntax
The grid
property syntax matches the grid-template
property, plus an additional syntax for defining auto-flow grids:
grid: <'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
- Initial value: as each of the properties of the shorthand.
- Applies to: grid containers
- Inherited: no
- Computed value: as specified, but with relative lengths converted into absolute lengths for
grid-template-columns
andgrid-template-rows
and the percentage as specified or the absolute length forgrid-auto-rows
andgrid-auto-columns
properties. - Animation type: simple list of length, percentage, or calc, provided the only differences are in the values of the length, percentage, or calc components in the list for
grid-template-columns
andgrid-template-rows
and discrete for the other properties of the shorthand.
Values
/* <'grid-template'> values */
grid: "header header header"
"sidebar main main"
". footer footer";
grid: 100px 1fr / 300px 1fr;
grid: [line1] 100px / [sidebar] 250px [content] 1fr;
grid: repeat(4, auto) / repeat(4, minmax(100px, 1fr));
grid: [row1-top] "header header" 100px [row1-bottom]
"sidebar main" 1fr [row2-bottom] / [col1-start] 300px [col1-end] 1fr;
/* <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? values */
/* explicit rows / auto generated columns */
grid: 50% / auto-flow dense;
grid: 100px 1fr / auto-flow;
grid: repeat(5, [line] 20rem) / auto-flow 15rem;
grid: min-content minmax(200px, 1fr) / auto-flow dense 300px;
/* [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'> values */
/* auto generated rows / explicit columns */
grid: auto-flow dense / 50%;
grid: auto-flow / 100px 1fr;
grid: auto-flow 15rem / repeat(5, [line] 20rem);
grid: auto-flow dense 300px / min-content minmax(200px, 1fr);
/* Global values */
grid: inherit;
grid: initial;
grid: revert;
grid: revert-layer;
grid: unset;
none
This is the default value. none
sets all sub-properties to their initial values which means there are no named grid areas, and no explicit grid tracks that this property defines on the grid container.
It also means that grid tracks are implicitly generated, and sized by the grid-auto-columns
and grid-auto-rows
properties — both of which the none
keyword sets to auto
and the auto-placement algorithm is set to the initial value, which is row
.
grid: none;
/* basically the same as saying */
grid-template-rows: none;
grid-template-columns: none;
grid-template-areas: none;
grid-auto-flow: row;
grid-auto-rows: auto;
grid-auto-columns: auto;
<'grid-template'>
You can use the grid
property as grid-template
to define explicit rows, columns, and areas.
Here, we describe how this syntax works but you can refer to the grid-template
` property for complete information.
<'grid-template-rows'> / <'grid-template-columns'>
This form of the grid
syntax defines rows and columns on a grid container in a single declaration while setting the grid-template-areas
value to none
. We split the values with a slash (/
) in between them like so:
.grid-container {
display: grid;
grid: min-content 1fr / 200px 1fr 200px;
}
…which is equivalent to writing this without a shorthand:
.grid-container {
display: grid;
grid-template-rows: min-content 1fr;
grid-template-columns: 200px 1fr 200px;
grid-template-areas: none;
}
The order matters. The values before the slash set the grid-template-rows
and the values after the slash set the grid-template-columns
property.
Here is another example where explicit line names are used to define our grid:
/* One row of 100px and two columns of 250px and 1fr: */
.grid-container {
display: grid;
grid: [line1] 100px / [sidebar] 250px [content] 1fr;
}
…which, again, is equivalent to writing it this way without the shorthand:
.grid-container {
display: grid;
grid-template-rows: [line1] 100px;
grid-template-columns: [sidebar] 250px [content] 1fr;
grid-template-areas: none;
}
[ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?
The grid
property also accepts a syntax that lets us explicitly specify the grid columns, rows, and areas at the same time.
grid:
"header header"
"sidebar main" 1fr
"footer footer" min-content
/ 200px 1fr;
/* Basically the same as: */
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 200px 1fr;
grid-template-rows: auto 1fr min-content;
header
, sidebar
, main
, and footer
are the names of the grid areas for a grid container. The number of names inside each string specifies the number of columns (which is two on each row in the example above).
The values after the columns — like 1fr
and min-content
above — represent the <track-size>
for each row. If we don’t specify a track size on a row, as in the first row of the example above, the size of that row is set to auto
.
The last line of the example contains a forward slash (/
) followed by two length values. Those set the column sizes. And since we have two columns on each row, we need to provide two sizes. We’ve set the first column to 200px
wide and the second row to 1fr
.
Be cautious when using the repeat()
function. It wasn’t designed to work with the <'grid-template'>
syntax of grid
property! The idea is that repeat()
would get in the way of being able to write things cleanly where everything can be lined up with whitespace — sort of like a simple visualization of the grid.
.grid {
display: grid;
grid: "header header"
"sidebar main" 1fr
"footer footer" min-content
/ 200px 1fr;
}
Note that repeat()
is not allowed only in this syntax but you can use it in other syntax versions of the grid
property.
<'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>?
This syntax forces you to define the rows explicitly, but on the other hand, the columns have to be declared implicitly. You need to write the value of grid-template-rows
on the left side of the slash and add auto-flow
keyword to the right side, which means the grid-auto-flow
is set to column
.
grid: 100px 1fr / auto-flow;
Also, you can add the dense
keyword to the right side to apply the dense auto-placement algorithm:
grid: 100px 1fr / auto-flow dense;
And, in case you want to set the size of your implicit columns by the grid-auto-columns
property, you can add the value to the right side:
grid: 100px 1fr / auto-flow dense 250px;
/* without dense */
grid: 100px 1fr / auto-flow 250px;
If you omit the dense
value, grid-auto-columns
will reset to auto
, which is its initial value. And, since we are using grid
shorthand property, all of the other sub-properties that we don’t set any values for will also be set to their initial values.
grid: 100px 1fr / auto-flow;
/* is equivalent to: */
grid-template-rows: 100px 1fr;
grid-template-columns: none; /* cannot be set in this syntax */
grid-template-areas: none; /* cannot be set in this syntax */
grid-auto-rows: auto; /* cannot be set in this syntax */
grid-auto-columns: auto;
grid-auto-flow: column; /* can only add dense */
As mentioned before, this syntax forces a grid with explicit rows and implicit columns — that’s why there are some limitations with the values you see in the code above. For example, the grid-template-columns
and the grid-template-areas
declarations define an explicit grid, which is unallowed in this syntax.
auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
[As opposed to the previous syntax, this syntax forces you to define the columns explicitly, but on the other hand, the rows have to be declared implicitly. In other words, you need to write the value of grid-template-columns
on the right side of the slash and add auto-flow
keyword to the left side, which means the grid-auto-flow
is set to row
.
Let’s see an example:
grid: auto-flow / 100px 1fr;
You can add the dense
keyword to the left side to apply the dense auto-placement algorithm:
grid: auto-flow dense / 100px 1fr;
And, in case you want to set the size of your implicit rows by the grid-auto-rows
property, you can add the value to the left side:
grid: auto-flow dense 250px / 100px 1fr;
/* without dense */
grid: auto-flow 250px / 100px 1fr;
If you omit the dense
value, grid-auto-rows
will reset to auto
, which is its initial value. And, since we are using grid
shorthand property, all of the other sub-properties that we don’t set any values for will also be set to their initials.
grid: auto-flow / 100px 1fr;
/* is equivalent to: */
grid-template-columns: 100px 1fr;
grid-template-rows: none; /* cannot be set in this syntax */
grid-template-areas: none; /* cannot be set in this syntax */
grid-auto-columns: auto; /* cannot be set in this syntax */
grid-auto-rows: auto;
grid-auto-flow: row; /* can only add dense */
As mentioned before, this syntax forces a grid with explicit rows and implicit columns and that’s why there are some limitations with the values you see in the code above. For example, the grid-template-rows
and the grid-template-areas
declarations define an explicit grid, which is unallowed in this syntax.
grid
shorthand does not reset gap properties
The In the first draft of CSS Grid Specifications, the grid
property was used to reset the gutter properties too, but that changed in 2017. So, grid
property no longer affects the gaps in a grid layout.
Example
Consider a gallery with eight columns and an unknown number of rows. Odd rows are 100 pixels tall and even rows are 200 pixels tall. Also, some images need to display at a larger size than the others and we don’t want any holes to appear between the items.
Since the columns are explicitly given, we start establishing our grid with the following code:
.gallery {
display: grid;
grid-template-columns: repeat(8, 1fr);
gap: 1rem;
}
As for the rows, we can’t set them explicitly since we don’t know how many of them we need.
Also, as explained above, there needs to be a repeatable and alternating pattern of 100px
and 200px
row sizes. We set the grid-auto-rows
like this:
.gallery {
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-auto-rows: 100px 200px;
gap: 1rem;
}
.gallery li:nth-child(2),
.gallery li:nth-child(4),
.gallery li:nth-child(6) {
grid-column: span 2;
grid-row: span 2;
}
To remove the empty spaces in the above grid we set grid-auto-flow
to dense
:
.gallery {
display: grid;
grid-template-columns: repeat(8, 1fr);
grid-auto-rows: 100px 200px;
grid-auto-flow: dense;
gap: 1rem;
}
And we have what we want:
We built all this to show you the magic of defining the whole scenario in a single declaration, thanks to the grid
property.
.gallery {
display: grid;
grid: auto-flow dense 100px 200px / repeat(8, 1fr);
gap: 1rem;
}
Also, check out the grid-template
property for more examples of <'grid-template'>
syntax form of the grid
property.
Browser support
Specification
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-template
.element { grid-template: 100px 1fr / 300px 1fr; }
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; }