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.

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!

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 Properties

Propertires for the Grid Container

  • display
  • grid-template-columns
  • grid-template-rows
  • grid-template-areas
  • grid-template
  • grid-column-gap
  • grid-row-gap
  • grid-gap
  • justify-items
  • align-items
  • justify-content
  • align-content
  • grid-auto-columns
  • grid-auto-rows
  • grid-auto-flow
  • grid

Properties for the Grid Item

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end
  • grid-column
  • grid-row
  • grid-area
  • justify-self
  • align-self

display

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

Values:

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

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

grid-template-columns

Defines the columns 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:

.container {
    grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
 }

grid-template-rows

Defines the 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:

.container {
    grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
 }

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:

.container {
    grid-template-areas: 
        "<grid-area-name> | . | none | ..."
        "...";
 }

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

grid-gap

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

Values:

.container {
    grid-gap: <grid-row-gap> <grid-column-gap>;
 }

Example:

.container {
    grid-gap: 20px;
 }

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