HTML & CSS
Article

An Introduction to the CSS Grid Layout Module

By Ahmad Ajmi

As web applications become more and more complex, we need a more natural way to do advanced layouts easily without hacky solutions that use floats and other less burdensome techniques. An exciting new solution for creating layouts comes with the CSS Grid Layout Module.

In this introductory tutorial, I’ll introduce you to this relatively new CSS feature, I’ll discuss the current browser support, and I’ll show you using some examples how the CSS Grid Layout Module works.

What is the CSS Grid Layout Module?

The core idea behind the Grid Layout is to divide a web page into columns and rows, along with the ability to position and size the building block elements based on the rows and columns we have created in terms of size, position, and layer.

The grid also gives us a flexible way to change the position of elements with only CSS without any change to the HTML. This can be used with media queries to alter the layout at different breakpoints.

Browser Support

Before we can dive more into Grid Layout, it’s good to know the status of browser support, and how we can enable this feature in current browsers.

Browser support for CSS Grid Layout Module

Internet Explorer

The first proposal of Grid Layout was developed by Microsoft, and IE10 shipped with an -ms prefixed implementation. If you take a look at support on Can I Use, you’ll see that both IE11 and Edge also support Grid Layout.

Chrome and Opera

To enable Grid Layout in browsers that use the Blink rendering engine, like Chrome or Opera, navigate to chrome://flags (or opera://flags, but either works in Opera) using the browser’s address bar and look for the Enable experimental Web Platform features flag. After you enable it, you will be asked to relaunch the browser.

Enabling Grid Layout in Chrome

It’s recommended to use either Chrome or Opera with the examples in this article, or with your own experimentations, as the Blink engine has the most updated implementationsof Grid Layout.

Firefox

Navigate to about:config, search for the layout.css.grid.enabled flag, then double click or press enter to toggle it to true.

Enabling Grid Layout in Firefox

Grid Layout Polyfill

A polyfill is also available to provide a working implementation of the Grid Module for current browsers.

A Grid Layout Example

Let’s start with an example to see the power of Grid Layout, and then I’ll explain some new concepts in more detail.

Imagine you want to create a Twitter app with four full height columns layout (Tweets, Replies, Search, and Messages), something abstracted and similar to the screenshot below.

4 Column Layout

Here is our HTML:

<div class="app-layout">
  <div class="tweets">Tweets</div>
  <div class="replies">Replies</div>
  <div class="search">Search</div>
  <div class="messages">Messages</div>
</div>

Then we will apply some CSS to the .app-layout container element:

.app-layout {
  display: grid; /* 1 */
  grid-template-columns: 1fr 1fr 1fr 1fr; /* 2 */
  grid-template-rows: 100vh; /* 3 */
}

View a demo here

Here is the explanation of what we’ve done in the previous CSS:

  1. Set the display property to grid.
  2. Divide the container element into four columns, each column is 1fr (one fraction) of the free space within the grid container.
  3. Create one row and set the height to be 100vh (full viewport height).

As you can see, the Grid Layout Module adds a new value to the display property which is grid. The grid value is responsible for setting the .app-layout element to be a grid container, which also establishes a new grid formatting context for its contents. This property is required to start using Grid Layout.

The grid-template-columns property specifies the width of each grid column within the Grid, and in our case it divides the .app-layout container to four columns; each one is 1fr (25%) of the available space.

The grid-template-rows specifies the height of each grid row, and in our example we only created one row at 100vh.

a layout with two columns and two rows would look like this:

4 columns, 2 rows

And we would use the following CSS:

.app-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 50vh 50vh;
}

View a demo here

We can also achieve the above example only on small screens by wrapping the code inside a media query. This opens up a great opportunity for us to customize the layout differently in different viewports. For example, we can create the previous layout only on viewports under 1024px as follows:

@media screen and (max-width: 1024px) {
  .app-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 50vh 50vh;
  }
}

View a demo here

Grid Layout Module Concepts

Now that you’ve seen a simple example, there are some new concepts that I’d like to cover to give you a better understanding of Grid Layout. Although there are a lot of new concepts, I will only take a look at a few of them.

Grid Item
Grid items are the child elements of the grid container. In the above example, the .tweets, and .replies elements would qualify as grid items.

Grid Lines
Mockup of Grid Lines in Grid Layout Module

A Grid Line is a line that exists on either side of a column or a row. There are two sets of grid lines: One set defining columns (the vertical axis), and another set defining rows (the horizontal axis).

From the above screenshot, which represents the first example, I’ve created four columns at 1fr each, which will give us five vertical lines. I also created one row, which gives us two horizontal lines.

Let’s see how we can position a grid item inside the grid container.

Position Items by Using a Line Number

You can refer to an exact line number in a grid by using the properties grid-column-start and grid-column-end. We then give these properties the start and end line numbers.

Looking at the previous example, this is how the browser positions the elements by default for us:

.tweets   {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row: 1;
}

.replies  {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row: 1;
}

.search   {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row: 1;
}

.messages {
  grid-column-start: 4;
  grid-column-end: 5;
  grid-row: 1;
}

Looking at the code for the .tweet column, this is what each of the three lines in the CSS does:

  1. Position the child element starting from the first vertical line on the left.
  2. End the element’s position at the second vertical line.
  3. Position the element inside the whole row.

You can change this by changing the order of elements with different positions, so the order of the elements will be: .search, .replies, .messages, and .tweets.

Changing the order of the columns with Grid Layout

And we can do it as follows:

.tweets {
  grid-column-start: 4;
  grid-column-end: 5;
  grid-row: 1;
}

.replies {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row: 1;
}

.search {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row: 1;
}

.messages {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row: 1;
}

We can also use the grid-column shorthand property to set the start and end lines in one line:

.tweets {
  grid-column: 4 / 5;
  grid-row: 1;
}

.replies {
  grid-column: 2 / 3;
  grid-row: 1;
}

.search {
  grid-column: 1 / 2;
  grid-row: 1;
}

.messages {
  grid-column: 3 / 4;
  grid-row: 1;
}

View a demo here

This has changed the layout structure with only CSS while the markup is still as it was without any changes. This is a huge advantage of using the Grid Layout Module. We can rearrange the layout of elements independent of their source order, so we can achieve any desired layout for different screen sizes and orientations.

Position Items by Using Named Areas

A grid area is the logical space used to lay out one or more grid items. We can name a grid area explicitly using the grid-template-areas property, then we can place a grid item into a specific area using the grid-area property.

To make this concept more clear, let’s redo the four-column example with the search column placed first:

.app-layout {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 100vh;
  grid-template-areas: "search replies messages tweets";
}

In the last line, we divide the grid container into four named grid areas, each name for a column. The next step is to position each grid item into a named area:

.search {
  grid-area: search;
}

.replies {
  grid-area: replies;
}

.messages {
  grid-area: messages;
}

.tweets {
  grid-area: tweets;
}

View a demo here

Slack Example

What about using the Grid Layout Module to implement a more complex example, for example, creating the building blocks of the Slack layout. Since we are talking about layouts, we will abstract and simplify the Slack design to the building blocks represented in the grid. Something like this:

The Slack Layout

From this layout we will create three vertical columns, and three horizontal rows, and we can visualize it using the grid lines as follows:

Mockup of the grid lines in the Slack layout

Here is the HTML:

<div class="app-layout">
  <div class="teams">Teams</div>
  <div class="channels">Channels</div>
  <div class="header">Header</div>
  <div class="messages">
    <ul class="message-list">
      <li></li>
      <li></li>
    </ul>
  </div>
  <div class="input">
    <input type="text" placeholder="CSS Grid Layout Module">
  </div>
</div>

And the CSS:

.app-layout {
  display: grid;
  height: 100vh;
  grid-template-columns: 100px 250px 1fr;
  grid-template-rows: auto 1fr auto;
}

Here I’m using the grid-template-columns property to create three columns at 100px, 250px, and the third column takes up the remaining available space. The last line creates three rows: The first and third rows with auto height while the middle row takes up the remaining available space.

The remainder of the CSS looks like this:

.teams {
  grid-column: 1;
  grid-row: 1 / 4;
}

.channels {
  grid-column: 2;
  grid-row: 1 / 4;
}

.header {
  grid-column: 3;
  grid-row: 1;
}

.messages {
  grid-column: 3;
  grid-row: 2;
}

.input {
  grid-column: 3;
  grid-row: 3;
}

View a demo here

We can also create the slack layout using named areas, which you can see in this demo.

Grid Layout Module vs Flexbox

Since many of you have started using Flexbox, you might wonder: When would it be appropriate to use Flexbox and when would it be more appropriate to use Grid Layout?

I found a good explanation from Tab Atkins:

Flexbox is appropriate for many layouts, and a lot of “page component” elements, as most of them are fundamentally linear. Grid is appropriate for overall page layout, and for complicated page components which aren’t linear in their design.

The two can be composed arbitrarily, so once they’re both widely supported, I believe most pages will be composed of an outer grid for the overall layout, a mix of nested flexboxes and grid for the components of the page, and finally block/inline/table layout at the “leaves” of the page, where the text and content live

Also, Rachel Andrew says:

Grid Layout for the main page structure of rows and columns.

Flexbox for navigation, UI elements, anything you could linearize.

CSS Grid Layout Module Resources

I have not covered all the Grid Layout concepts and syntax, so I recommend you check out the following resources to go deeper:

Conclusion

As you’ve seen, the upcoming CSS Grid Layout Module is powerful because of its code brevity and the fact that you have the power to change the layout order without touching the markup. These features can help us permanently change the way we create layouts for the web.

  • Juggler

    This is enlightning. Thank you Ahmad!

    • http://ahmadajmi.com/ Ahmad Ajmi

      Yes, it’s very enlightening and promising. Thanks for reading, glad you find it useful!

  • tomByrer

    Works in my Firefox Dev 46 with out flag (see updated chart in CanIUse).

    • http://ahmadajmi.com/ Ahmad Ajmi

      That’s a very great update, also supported in Chrome 50. Thanks for letting us know!

  • 刘谦

    Fantastic!

  • John Domitila

    Thank you for this article… was helpful

    • http://aspirethemes.com/ Ahmad Ajmi (AT)

      Thanks John, so glad about this!

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in Front-end, once a week, for free.