A Complete Guide To Grid
A Complete Guide To Grid
A Complete Guide To Grid
CSS Grid Layout is the most powerful layout system available in CSS. It is a 2-dimensional system,
meaning it can handle both columns and rows, unlike flexbox which is largely a 1-dimensional
system. You work with Grid Layout by applying CSS rules both to a parent element (which becomes
the Grid Container) and to that elements children (which become Grid Items).
This article was originally ported over from Chris House's guide, and has since been keep up to date by CSS-Tricks staff and paid
writers.
▼ Introduction
CSS Grid Layout (aka "Grid"), is a two-dimensional grid-based layout system that aims to do
nothing less than completely change the way we design grid-based user interfaces. CSS has
always been used to lay out our web pages, but it's never done a very good job of it. First, we
used tables, then floats, positioning and inline-block, but all of these methods were essentially
hacks and left out a lot of important functionality (vertical centering, for instance). Flexbox
helped out, but it's intended for simpler one-dimensional layouts, not complex two-
dimensional ones (Flexbox and Grid actually work very well together). Grid is the very first CSS
module created specifically to solve the layout problems we've all been hacking our way
around for as long as we've been making websites.
There are two primary things that inspired me to create this guide. The first is Rachel Andrew's
awesome book Get Ready for CSS Grid Layout. It's a thorough, clear introduction to Grid and is
the basis of this entire article. I highly encourage you to buy it and read it. My other big
inspiration is Chris Coyier's A Complete Guide to Flexbox, which has been my go-to resource
for everything flexbox. It's helped a ton of people, evident by the fact that it's the top result
when you Google "flexbox." You'll notice many similarities between his post and mine,
because why not steal from the best?
My intention with this guide is to present the Grid concepts as they exist in the very latest
version of the specification. So I won't be covering the out of date IE syntax, and I'll do my best
to update this guide regularly as the spec matures.
▼ Basics and Browser Support
To get started you have to define a container element as a grid with display: grid , set the
column and row sizes with grid-template-columns and grid-template-rows , and then
place its child elements into the grid with grid-column and grid-row . Similarly to flexbox,
the source order of the grid items doesn't matter. Your CSS can place them in any order, which
makes it super easy to rearrange your grid with media queries. Imagine defining the layout of
your entire page, and then completely rearranging it to accommodate a different screen width
all with only a couple lines of CSS. Grid is one of the most powerful CSS modules ever
introduced.
As of March 2017, most browsers shipped native, unprefixed support for CSS Grid: Chrome
(including on Android), Firefox, Safari (including on iOS), and Opera. Internet Explorer 10 and 11
on the other hand support it, but it's an old implementation with an outdated syntax. The time
to build with grid is now!
This browser support data is from Caniuse, which has more detail. A number indicates that browser
supports the feature at that version and up.
# Desktop
# Mobile / Tablet
iOS Safari: 10.3 Opera Mobile: 46 Opera Mini: No Android: 67 Android Chrome: 67
Android Firefox: 60
▼ Important Terminology
Before diving into the concepts of Grid it's important to understand the terminology. Since the
terms involved here are all kinda conceptually similar, it's easy to confuse them with one
another if you don't first memorize their meanings defined by the Grid specification. But don't
worry, there aren't many of them.
# Grid Container
The element on which display: grid is applied. It's the direct parent of all the grid items. In
this example container is the grid container.
html
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
# Grid Item
The children (e.g. direct descendants) of the grid container. Here the item elements are grid
items, but sub-item isn't.
html
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
# Grid Line
The dividing lines that make up the structure of the grid. They can be either vertical ("column
grid lines") or horizontal ("row grid lines") and reside on either side of a row or column. Here
the yellow line is an example of a column grid line.
# Grid Track
The space between two adjacent grid lines. You can think of them like the columns or rows of
the grid. Here's the grid track between the second and third row grid lines.
# Grid Cell
The space between two adjacent row and two adjacent column grid lines. It's a single "unit" of
the grid. Here's the grid cell between row grid lines 1 and 2, and column grid lines 2 and 3.
# Grid Area
The total space surrounded by four grid lines. A grid area may be comprised of any number of
grid cells. Here's the grid area between row grid lines 1 and 3, and column grid lines 1 and 3.
▼ Grid Properties Table of Contents
Properties for the Grid Container Properties for the Grid Items
display grid-column-start
grid-template-columns grid-column-end
grid-template-rows grid-row-start
grid-template-areas grid-row-end
grid-template grid-column
grid-column-gap grid-row
grid-row-gap grid-area
grid-gap justify-self
justify-items align-self
align-items place-self
place-items
justify-content
align-content
place-content
grid-auto-columns
grid-auto-rows
grid-auto-flow
grid
Values: css
.container {
Examples:
grid-template-columns: <
grid-template-rows: <tra css
}
.item-a {
grid-column-start: 2;
Examples:
grid-column-end: five;
When you leave an empty space grid-row-start: row1-sta
between the track values, the grid lines
grid-row-end: 3;
are automatically assigned positive and
negative numbers: }
css
.container {
grid-template-columns: 4
grid-template-rows: 25%
}
css
.item-b {
grid-column-start: 1;
grid-column-end: span co
grid-row-start: 2
grid-row-end: span 2
But you can choose to explicitly name }
the lines. Note the bracket syntax for the
line names:
css
.container {
grid-template-columns: [
grid-template-rows: [row
}
If no grid-column-end / grid-row-
end is declared, the item will span 1
track by default.
Values:
.container {
grid-template-rows: [row <start-line> / <end-line> - each
one accepts all the same values
}
as the longhand version, including
span
.container { .item-c {
grid-template-columns: 2 grid-column: 3 / span 2;
} grid-row: third-line / 4
}
css
.item {
grid-column-start: col-s
}
.item {
# grid-template-areas
grid-area: <name> | <row
Defines a grid template by referencing }
the names of the grid areas which are
specified with the grid-area property.
Repeating the name of a grid area
Examples:
causes the content to span those cells.
A period signifies an empty cell. The As a way to assign a name to the item:
syntax itself provides a visualization of
the structure of the grid. css
Values:
.item-d {
<grid-area-name> - the name of grid-area: header
a grid area specified with grid-
}
area
css
.container {
grid-template-areas: .item-d {
"<grid-area-name> | . grid-area: 1 / col4-star
"..."; }
}
Example:
css
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
# justify-self
.item-c { Aligns a grid item inside a cell along the
inline (row) axis (as opposed to align-
grid-area: sidebar;
self which aligns along the block
} (column) axis). This value applies to a
.item-d { grid item inside a single cell.
}
.item {
justify-self: start | en
That'll create a grid that's four columns
wide by three rows tall. The entire top }
row will be comprised of the header
area. The middle row will be comprised
of two main areas, one empty cell, and Examples:
one sidebar area. The last row is all
footer. css
.item-a {
justify-self: start;
}
Values:
CSS
.container {
grid-template: none | <g
}
To set alignment for all the items in a
grid, this behavior can also be set on the
It also accepts a more complex but quite grid container via the justify-items
handy syntax for specifying all three. property.
Here's an example:
css
# align-self
.container {
Aligns a grid item inside a cell along the
grid-template:
block (column) axis (as opposed to
[row1-start] "header h justify-self which aligns along the
# grid-column-gap
grid-row-gap
Specifies the size of the grid lines. You
can think of it like setting the width of
the gutters between the columns/rows.
Values:
css
.item-a {
.container { align-self: end;
grid-column-gap: <line-s }
grid-row-gap: <line-size
}
Example:
css
css
.container {
grid-template-columns: 1
.item-a {
grid-template-rows: 80px
align-self: center;
grid-column-gap: 10px;
}
grid-row-gap: 15px;
}
css
.item-a {
align-self: stretch;
}
# grid-gap
css Examples:
css
.container {
grid-template-columns: 1
.item-a {
grid-template-rows: 80px
place-self: center;
grid-gap: 15px 10px;
}
}
.item-a {
place-self: center stret
# justify-items }
Values:
start - aligns items to be flush All major browsers except Edge support
with the start edge of their cell the place-self shorthand property.
end - aligns items to be flush with
the end edge of their cell
center - aligns items in the center
of their cell
stretch - fills the whole width of
the cell (this is the default)
css
.container {
justify-items: start | e
}
Examples:
css
.container {
justify-items: start;
}
css
.container{
justify-items: end;
}
css
.container {
justify-items: center;
}
css
.container {
justify-items: stretch;
}
This behavior can also be set on
individual grid items via the justify-
self property.
# align-items
Values:
css
.container {
align-items: start | end
}
Examples:
css
.container {
align-items: start;
}
css
.container {
align-items: end;
}
css
.container {
align-items: center;
}
css
.container {
align-items: stretch;
}
This behavior can also be set on
individual grid items via the align-
self property.
# place-items
Values:
<align-items> / <justify-items> -
The first value sets align-
items , the second value
justify-items . If the second
value is omitted, the first value is
assigned to both properties.
# justify-content
Values:
css
.container {
justify-content: start |
}
Examples:
css
.container {
justify-content: start;
}
css
.container {
justify-content: end;
}
css
.container {
justify-content: center;
}
css
.container {
justify-content: stretch
}
css
.container {
justify-content: space-a
}
css
.container {
justify-content: space-b
}
css
.container {
justify-content: space-e
}
# align-content
Values:
css
.container {
align-content: start | e
}
Examples:
css
.container {
align-content: start;
}
css
.container {
align-content: end;
}
css
.container {
align-content: center;
}
css
.container {
align-content: stretch;
}
css
.container {
align-content: space-aro
}
css
.container {
align-content: space-bet
}
css
.container {
align-content: space-eve
}
# place-content
<align-content> / <justify-
content> - The first value sets
align-content , the second
value justify-content . If the
second value is omitted, the first
value is assigned to both
properties.
# grid-auto-columns
grid-auto-rows
Specifies the size of any auto-generated
grid tracks (aka implicit grid tracks).
Implicit tracks get created when there
are more grid items than cells in the grid
or when a grid item is placed outside of
the explicit grid. (see The Difference
Between Explicit and Implicit Grids)
Values:
css
.container {
grid-auto-columns: <trac
grid-auto-rows: <track-s
}
To illustrate how implicit grid tracks get
created, think about this:
css
.container {
grid-template-columns: 6
grid-template-rows: 90px
}
css
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
css
.container {
grid-auto-columns: 60px;
}
# grid-auto-flow
If you have grid items that you don't
explicitly place on the grid, the auto-
placement algorithm kicks in to
automatically place the items. This
property controls how the auto-
placement algorithm works.
Values:
css
.container {
grid-auto-flow: row | co
}
Examples:
html
<section class="container"
<div class="item-a">item
<div class="item-b">item
<div class="item-c">item
<div class="item-d">item
<div class="item-e">item
</section>
css
.container {
display: grid;
grid-template-columns: 6
grid-template-rows: 30px
grid-auto-flow: row;
}
css
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
css
.container {
display: grid;
grid-template-columns: 6
grid-template-rows: 30px
grid-auto-flow: column;
}
# grid
Values:
Examples:
css
.container {
grid: 100px 300px / 3f
}
css
.container {
grid-template-rows: 10
grid-template-columns:
}
The following two code blocks are
equivalent:
css
.container {
grid: auto-flow / 200p
}
css
.container {
grid-auto-flow: row;
grid-template-columns:
}
css
.container {
grid: auto-flow dense
}
css
.container {
grid-auto-flow: row de
grid-auto-rows: 100px;
grid-template-columns:
}
.container {
grid: 100px 300px / au
}
css
.container {
grid-template-rows: 10
grid-auto-flow: column
grid-auto-columns: 200
}
css
.container {
grid: [row1-start] "he
[row2-start] "fo
/ auto 50px auto
}
.container {
grid-template-areas:
"header header heade
"footer footer foote
grid-template-rows: [r
grid-template-columns:
}
▶Animation
Comments