Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

A Complete Guide To Grid

Download as pdf or txt
Download as pdf or txt
You are on page 1of 39

Home » Code Snippets » CSS »

A Complete Guide to Grid


BY CHRIS HOUSE LAST UPDATED ON AUGUST 20, 2018
CSS GRID, 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

Chrome: 57 Opera: 44 Firefox: 52 IE: 11* Edge: 16 Safari: 10.1

# 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

Properties for the Parent Properties for the


(Grid Container) Children
(Grid Items)
# display

Defines the element as a grid container


Note:
and establishes a new grid formatting float , display: inline-block ,
context for its contents.
display: table-cell , vertical-
align and column-* properties have
Values:
no effect on a grid item.
grid - generates a block-level grid
inline-grid - generates an inline-
level grid
# grid-column-start
css
grid-column-end
.container { grid-row-start
display: grid | inline-g
grid-row-end
Determines a grid item's location within
}
the grid by referring to specific grid
lines. grid-column-start / grid-row-
start is the line where the item begins,
Note: The ability to pass grid
and grid-column-end / grid-row-
parameters down through nested
end is the line where the item ends.
elements (aka subgrids) has been
moved to level 2 of the CSS Grid Values:
specification. Here's a quick
explanation. <line> - can be a number to refer
to a numbered grid line, or a name
to refer to a named grid line
span <number> - the item will
span across the provided number
# grid-template-columns
of grid tracks
grid-template-rows span <name> - the item will span
Defines the columns and rows of the across until it hits the next line
grid with a space-separated list of with the provided name
values. The values represent the track auto - indicates auto-placement,
size, and the space between them an automatic span, or a default
represents the grid line. span of one

Values: css

<track-size> - can be a length, a


percentage, or a fraction of the .item {
free space in the grid (using the
grid-column-start: <numb
fr unit)
grid-column-end: <number
<line-name> - an arbitrary name grid-row-start: <number>
of your choosing
grid-row-end: <number> |
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.

Items can overlap each other. You can


use z-index to control their stacking
order.

Note that a line can have more than one


# grid-column
name. For example, here the second line
will have two names: row1-end and grid-row
row2-start: Shorthand for grid-column-start +
grid-column-end , and grid-row-
css
start + grid-row-end , respectively.

Values:
.container {
grid-template-rows: [row <start-line> / <end-line> - each
one accepts all the same values
}
as the longhand version, including
span

If your definition contains repeating css


parts, you can use the repeat()
notation to streamline things:
.item {
css grid-column: <start-line
grid-row: <start-line> /
.container {
}
grid-template-columns: r
}
Example:

Which is equivalent to this:


css css

.container { .item-c {
grid-template-columns: 2 grid-column: 3 / span 2;
} grid-row: third-line / 4
}

If multiple lines share the same name,


they can be referenced by their line
name and count.

css

.item {
grid-column-start: col-s
}

If no end line value is declared, the item


The fr unit allows you to set the size
will span 1 track by default.
of a track as a fraction of the free space
of the grid container. For example, this
will set each item to one third the width
of the grid container:
# grid-area
css
Gives an item a name so that it can be
referenced by a template created with
.container { the grid-template-areas property.
grid-template-columns: 1 Alternatively, this property can be used
as an even shorter shorthand for grid-
}
row-start + grid-column-start +
grid-row-end + grid-column-end .

The free space is calculated after any Values:


non-flexible items. In this example the
total amount of free space available to <name> - a name of your
the fr units doesn't include the 50px: choosing
<row-start> / <column-start> /
css <row-end> / <column-end> - can
be numbers or named lines
.container {
grid-template-columns: 1
}
css

.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

. - a period signifies an empty grid


cell
As the short-shorthand for grid-row-
none - no grid areas are defined start + grid-column-start + grid-
row-end + grid-column-end :
css

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.

grid-area: footer; Values:


}
start - aligns the grid item to be
flush with the start edge of the
.container { cell

grid-template-columns: 5 end - aligns the grid item to be


flush with the end edge of the cell
grid-template-rows: auto
center - aligns the grid item in the
grid-template-areas: center of the cell
"header header header stretch - fills the whole width of
"main main . sidebar" the cell (this is the default)

"footer footer footer css

}
.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;
}

Each row in your declaration needs to


have the same number of cells.

You can use any number of adjacent


periods to declare a single empty cell.
As long as the periods have no spaces
between them they represent a single css
cell.

Notice that you're not naming lines with .item-a {


this syntax, just areas. When you use justify-self: end;
this syntax the lines on either end of the
}
areas are actually getting named
automatically. If the name of your grid
area is foo, the name of the area's
starting row line and starting column
line will be foo-start, and the name of
its last row line and last column line will
be foo-end. This means that some lines
might have multiple names, such as the
far left line in the above example, which
will have three names: header-start, css

main-start, and footer-start.


.item-a {
justify-self: center;
}
# grid-template

A shorthand for setting grid-


template-rows , grid-template-
columns , and grid-template-areas
in a single declaration.

Values:

none - sets all three properties to


css
their initial values
<grid-template-rows> / <grid-
template-columns> - sets grid- .item-a {
template-columns and grid- justify-self: stretch;
template-rows to the specified
}
values, respectively, and sets
grid-template-areas to none

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

[row2-start] "footer f inline (row) axis). This value applies to


the content inside a single grid item.
/ auto 50px auto;
} Values:

start - aligns the grid item to be


flush with the start edge of the
That's equivalent to this: cell

css end - aligns the grid item to be


flush with the end edge of the cell
center - aligns the grid item in the
.container {
center of the cell
grid-template-rows: [row
stretch - fills the whole height of
grid-template-columns: a the cell (this is the default)
grid-template-areas:
css
"header header header"
"footer footer footer" .item {
} align-self: start | end
}
Since grid-template doesn't reset the
implicit grid properties ( grid-auto-
columns , grid-auto-rows , and Examples:
grid-auto-flow ), which is probably
css
what you want to do in most cases, it's
recommended to use the grid
property instead of grid-template . .item-a {
align-self: start;
}

# 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:

<line-size> - a length value


css

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;
}

The gutters are only created between


the columns/rows, not on the outer
edges.
Note: The grid- prefix will be
removed and grid-column-gap and
grid-row-gap renamed to column-
gap and row-gap . The unprefixed
properties are already supported in
Chrome 68+, Safari 11.2 Release 50+ and
Opera 54+. To align all the items in a grid, this
behavior can also be set on the grid
container via the align-items
property.

# grid-gap

A shorthand for grid-row-gap and


grid-column-gap
# place-self
Values: place-self sets both the align-
self and justify-self properties in
<grid-row-gap> <grid-column-
a single declaration.
gap> - length values
Values:
css

auto - The “default” alignment for


.container { the layout mode.
<align-self> / <justify-self> -
grid-gap: <grid-row-gap>
The first value sets align-self ,
} the second value justify-self .
If the second value is omitted, the
first value is assigned to both
Example: properties.

css Examples:

css
.container {
grid-template-columns: 1
.item-a {
grid-template-rows: 80px
place-self: center;
grid-gap: 15px 10px;
}
}

If no grid-row-gap is specified, it's set


to the same value as grid-column-gap

Note: The grid- prefix will be


removed and grid-gap renamed to
gap . The unprefixed property is
already supported in Chrome 68+, Safari css
11.2 Release 50+ and Opera 54+.

.item-a {
place-self: center stret
# justify-items }

Aligns grid items along the inline (row)


axis (as opposed to align-items
which aligns along the block (column)
axis). This value applies to all grid items
inside the container.

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

Aligns grid items along the block


(column) axis (as opposed to justify-
items which aligns along the inline
(row) axis). This value applies to all grid
items inside the container.

Values:

start - aligns items to be flush


with the start edge of their cell
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 height of
the cell (this is the default)

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

place-items sets both the align-


items and justify-items properties
in a single declaration.

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.

All major browsers except Edge support


the place-items shorthand property.

For more details, see align-items and


justify-items.

# justify-content

Sometimes the total size of your grid


might be less than the size of its grid
container. This could happen if all of
your grid items are sized with non-
flexible units like px . In this case you
can set the alignment of the grid within
the grid container. This property aligns
the grid along the inline (row) axis (as
opposed to align-content which
aligns the grid along the block (column)
axis).

Values:

start - aligns the grid to be flush


with the start edge of the grid
container
end - aligns the grid to be flush
with the end edge of the grid
container
center - aligns the grid in the
center of the grid container
stretch - resizes the grid items to
allow the grid to fill the full width
of the grid container
space-around - places an even
amount of space between each
grid item, with half-sized spaces
on the far ends
space-between - places an even
amount of space between each
grid item, with no space at the far
ends
space-evenly - places an even
amount of space between each
grid item, including the far ends

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

Sometimes the total size of your grid


might be less than the size of its grid
container. This could happen if all of
your grid items are sized with non-
flexible units like px . In this case you
can set the alignment of the grid within
the grid container. This property aligns
the grid along the block (column) axis
(as opposed to justify-content
which aligns the grid along the inline
(row) axis).

Values:

start - aligns the grid to be flush


with the start edge of the grid
container
end - aligns the grid to be flush
with the end edge of the grid
container
center - aligns the grid in the
center of the grid container
stretch - resizes the grid items to
allow the grid to fill the full height
of the grid container
space-around - places an even
amount of space between each
grid item, with half-sized spaces
on the far ends
space-between - places an even
amount of space between each
grid item, with no space at the far
ends
space-evenly - places an even
amount of space between each
grid item, including the far ends

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

place-content sets both the align-


content and justify-content
properties in a single declaration.
Values:

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

All major browsers except Edge support


the place-content shorthand
property.

For more details, see align-content and


justify-content.

# 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:

<track-size> - can be a length, a


percentage, or a fraction of the
free space in the grid (using the
fr unit)

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
}

This creates a 2 x 2 grid.

But now imagine you use grid-column


and grid-row to position your grid
items like this:

css

.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}

We told .item-b to start on column line 5


and end at column line 6, but we never
defined a column line 5 or 6. Because we
referenced lines that don't exist, implicit
tracks with widths of 0 are created to fill
in the gaps. We can use grid-auto-
columns and grid-auto-rows to
specify the widths of these implicit
tracks:

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:

row - tells the auto-placement


algorithm to fill in each row in
turn, adding new rows as
necessary (default)
column - tells the auto-placement
algorithm to fill in each column in
turn, adding new columns as
necessary
dense - tells the auto-placement
algorithm to attempt to fill in
holes earlier in the grid if smaller
items come up later

css

.container {
grid-auto-flow: row | co
}

Note that dense only changes the visual


order of your items and might cause
them to appear out of order, which is
bad for accessibility.

Examples:

Consider this HTML:

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>

You define a grid with five columns and


two rows, and set grid-auto-flow to
row (which is also the default):

css

.container {
display: grid;
grid-template-columns: 6
grid-template-rows: 30px
grid-auto-flow: row;
}

When placing the items on the grid, you


only specify spots for two of them:

css

.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}

Because we set grid-auto-flow to


row , our grid will look like this. Notice
how the three items we didn't place
(item-b, item-c and item-d) flow across
the available rows:
If we instead set grid-auto-flow to
column , item-b, item-c and item-d
flow down the columns:

css

.container {
display: grid;
grid-template-columns: 6
grid-template-rows: 30px
grid-auto-flow: column;
}

# grid

A shorthand for setting all of the


following properties in a single
declaration: grid-template-rows ,
grid-template-columns , grid-
template-areas , grid-auto-rows ,
grid-auto-columns , and grid-auto-
flow (Note: You can only specify the
explicit or the implicit grid properties in
a single grid declaration).

Values:

none - sets all sub-properties to


their initial values.
<grid-template> - works the
same as the grid-template
shorthand.
<grid-template-rows> / [ auto-
flow && dense? ] <grid-auto-
columns>? - sets grid-
template-rows to the specified
value. If the auto-flow keyword
is to the right of the slash, it sets
grid-auto-flow to column . If
the dense keyword is specified
additionally, the auto-placement
algorithm uses a “dense” packing
algorithm. If grid-auto-columns
is omitted, it is set to auto .
[ auto-flow && dense? ] <grid-
auto-rows>? / <grid-template-
columns> - sets grid-template-
columns to the specified value. If
the auto-flow keyword is to the
left of the slash, it sets grid-
auto-flow to row . If the
dense keyword is specified
additionally, the auto-placement
algorithm uses a “dense” packing
algorithm. If grid-auto-rows is
omitted, it is set to auto .

Examples:

The following two code blocks are


equivalent:

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:
}

The following two code blocks are


equivalent:

css

.container {
grid: auto-flow dense
}

css

.container {
grid-auto-flow: row de
grid-auto-rows: 100px;
grid-template-columns:
}

And the following two code blocks are


equivalent:
css

.container {
grid: 100px 300px / au
}

css

.container {
grid-template-rows: 10
grid-auto-flow: column
grid-auto-columns: 200
}

It also accepts a more complex but quite


handy syntax for setting everything at
once. You specify grid-template-
areas , grid-template-rows and
grid-template-columns , and all the
other sub-properties are set to their
initial values. What you're doing is
specifying the line names and track
sizes inline with their respective grid
areas. This is easiest to describe with an
example:

css

.container {
grid: [row1-start] "he
[row2-start] "fo
/ auto 50px auto
}

That's equivalent to this:


css

.container {
grid-template-areas:
"header header heade
"footer footer foote
grid-template-rows: [r
grid-template-columns:
}

▶Animation
Comments

You might also like