CSS 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 ported over from Chris House's guide, by Chris himself, who is keeping both up-to-date.

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

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.

display

Defines the element as a grid container and establishes a new grid formatting context for its contents.

    Values:

  • grid - generates a block-level grid
  • inline-grid - generates an inline-level grid
  • subgrid - if your grid container is itself a grid item (i.e. nested grids), you can use this property to indicate that you want the sizes of its rows/columns to be taken from its parent rather than specifying its own.

Example:

.container {
display: grid | inline-grid | subgrid;
}

Note: column, float, clear, and vertical-align have no effect on a grid container.

grid-template-columns and grid-template-rows

Defines the columns and rows of the grid with a space-separated list of values. The values represent the track size, and the space between them represents the grid line.

    Values:

  • track-size tag - can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit)
  • line-name - an arbitrary name of your choosing

Example:

.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
fr:
The fr unit allows you to set the size 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-template-areas

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 causes the content to span those cells. A period signifies an empty cell. The syntax itself provides a visualization of the structure of the grid.

    Values:

  • grid-area-name - the name of a grid area specified with grid-area
  • . - a period signifies an empty grid cell.
  • none - no grid areas are defined.

Example

.item-a {
grid-area: header;
} .item-b {
grid-area: main;
} .item-c {
grid-area: sidebar;
} .item-d {
grid-area: footer;
} .container {
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}

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 one sidebar area. The last row is all footer.

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 their initial values
  • subgrid - sets grid-template-rows and grid-template-columns to subgrid, and grid-template-areas to its initial value
  • grid-template-columns and grid-template-rows - sets grid-template-columns and grid-template-rows to the specified values, respectively, and sets grid-template-areas to none
grid-column-gap and 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

Example

.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px;
grid-row-gap: 15px;
}

Note: The gutters are only created between the columns/rows, not on the outer edges.

grid-gap

A shorthand for grid-row-gap and grid-column-gap

    Values:

  • "grid-row-gap" & "grid-column-gap - length values.

Example

.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 10px 15px;
}

Note: If no grid-row-gap is specified, it's set to the same value as grid-column-gap

justify-items

Aligns the content inside a grid item along the row axis (as opposed to align-items which aligns along the column axis). This value applies to all grid items inside the container.

    Values:

  • start - aligns the content to the left end of the grid area
  • end - aligns the content to the right end of the grid area
  • center - aligns the content in the center of the grid area
  • stretch - fills the whole width of the grid area (this is the default)

Example

.container {
justify-items: end;
}

Note: This behavior can also be set on individual grid items via the justify-self property.

align-items

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

    Values:

  • start - aligns the content to the top of the grid area
  • end - aligns the content to the bottom of the grid area
  • center - aligns the content in the center of the grid area
  • stretch - fills the whole height of the grid area (this is the default)

Example

.container {
align-items: start;
}

Note: This behavior can also be set on individual grid items via the align-self property.

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 row axis (as opposed to align-content which aligns the grid along the column axis).

    Values:

  • start - aligns the grid to the left end of the grid container
  • end - aligns the grid to the right end 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

Example

.container {
justify-content: space-evenly;
}
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 column axis (as opposed to justify-content which aligns the grid along the row axis).

    Values:

  • start - aligns the grid to the top of the grid container
  • end - aligns the grid to the bottom 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, with no space at the far ends

Example

.container {
align-content: space-around;
}
grid-auto-columns and grid-auto-rows

Specifies the size of any auto-generated grid tracks (aka implicit grid tracks). Implicit grid tracks get created when you explicitly position rows or columns (via grid-template-rows/grid-template-columns) that are out of range of the defined grid.

    Values:

  • "track-size" - can be a length, a percentage, or a fraction of the free space in the grid (using the fr unit)

Example

.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px;
}
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
  • 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

Example

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

Note: dense might cause your items to appear out of order.

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. It also sets grid-column-gap and grid-row-gap to their initial values, even though they can't be explicitly set by this property.

    Values:

  • none - sets all sub-properties to their initial values
  • "grid-template-rows" & "grid-template-columns" - sets grid-template-rows and grid-template-columns to the specified values, respectively, and all other sub-properties to their initial values
  • "grid-auto-flow" ("grid-auto-rows" / "grid-auto-columns") - accepts all the same values as grid-auto-flow, grid-auto-rows and grid-auto-columns, respectively. If grid-auto-columns is omitted, it is set to the value specified for grid-auto-rows. If both are omitted, they are set to their initial values

Example

.container {
grid: column 1fr/ auto;
}