How To

Getting on the CSS Grid

13 Oct , 2017  

You know how much effort we put into arranging web pages right?

I just finished making a Bootstrap 4 course, and the whole purpose of Bootstrap is to arrange web pages reliably.

If they don’t want to use Bootstrap, web developers  had to use a combination of CSS hacks to arrange a web page, including:

  • Floating elements
  • Using a lot of display: inline-block
  • Adding a lot of special cases for different browsers

Lucky for us, we’ve got a new option: the CSS Grid.

Grid is a “new” layout system for CSS. When I say “new”, it’s really been floating around since 2014.

But now, nearly 70% of internet users have browsers that support grid, and that number’s rising fast.

With SmashingMagazine holding a competition for the creative use of CSS grid, we know it’s headed for the big time.

But what is it?

Simply put, this is a new value for the CSS rule display, and a series of new style rules we can use to define rows and columns on a web page.

Now, there’s a lot of new CSS rules for Grid, but today we’ll take a look at the ones you need to get a reliable, responsive grid layout.

In today’s article you’ll learn:

  • How to use display: grid
  • How you can set up a very simple grid display
  • How you can make your grid responsive

This article assumes some basic HTML and CSS knowledge. You can find a quick introduction to HTML here and CSS here.

Getting started with CSS Grid

The basic pattern for CSS Grid is: define a container class that describes rows and columns, and then populate the container.

Let’s try a simple example. I’ve downloaded some pictures of roads (because, why not?) from unsplash.com. I’ll display them in a simple grid. Here’s our CSS & HTML:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

img {
  width: 100%;
} 
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>CSS Grid</title>
  </head>
  <link rel="stylesheet" href="./css-grid-0-1.css">
  <body>

    <div class="container">
      
        <img src="road1.jpg">
        <img src="road2.jpg">
        <img src="road3.jpg">
        <img src="road4.jpg">

    </div>

  </body>
</html>

And here’s what the page looks like:

Basic CSS Grid 2 columns

Here’s our grid-specific CSS again:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

As you can see we’ve set the display to grid.

That grid-template-columns rule defines how many columns the grid has, and how much space each column occupies.

So what’s happened here is we’ve defined a grid with two columns, and stuck four pictures into it. The grid layout system automatically arranges the four images into two rows of two.

An fr, by the way, is a “fractional unit”. What this means is that if we specify only 1fr for a column, that 1fr will occupy all the available space.

If we have the columns set to 1fr 1fr, then each column with get 50% of the available space. Columns set to 1fr 1fr 1fr get a third each of the available space.

I find this such an absurdly intuitive way to define space, it’s almost counter intuitive.

“No, it can’t work like that,” I think, “it’s too simple.” But it is simple, and it works.

If we change our CSS to look like this:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

Then our four images will be organized into a single row on the page:

CSS Grid with 4 columns

Given our new-found knowledge for defining columns, let’s make this a little responsive now.

Responsive CSS Grid

For larg-er screens, we’ll have four columns, and two columns for smaller screens (the HTML hasn’t changed):

img {
  width: 100%;
  max-width: 500px;
} 

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@media (min-width: 768px) {
  .container {
    grid-template-columns: repeat(4, 1fr);
  }
}

What’s that, a repeat? Yes, instead of tediously typing all those 1frs, we can use repeat to define as many as we want.

Now we have some nicely displaying images with an incredibly small amount of CSS.

Happy days.

But this isn’t what the CSS Grid is for! It’s not for laying out individual elements in a page, but whole sections!

Let’s get serious with our grid layout.

CSS Grid: defining a head, footer and article body

To do this, we’ll use something called template areas.

Here’s our plan of attack:

  1. We add a header and footer to the page.
  2. We define how many columns each row should have.
  3. We define the size of the rows.
  4. We assign named-template-areas to web page sections like header, footer and article.

Here’s the CSS:

body {
  font-family: sans-serif;
  font-size: 16pt;
}

.container {
  display: grid;
  grid-template-columns: 0.25fr 1fr;
  grid-template-areas: "header header"
                      "nav body"
                      "footer footer";
  grid-gap: 1em;
}

header {
  justify-self: center;
  grid-area: header;
}

nav {
  align-self: center;
  grid-area: nav;
}

footer {
  justify-self: center;
  grid-area: footer;
}

article {
  grid-area: body;
  display: flex;
  flex-wrap: wrap;
}

img {
  width: 50%;
  height: auto;
  max-width: 220px;
} 

nav li {
  list-style-type: none;
}

nav li a {
  text-decoration: none;
}

And the HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>CSS Grid</title>
  </head>
  <link rel="stylesheet" href="./css-grid-0-3.css">
  <body>

    <div class="container">
      <header><h1>Roads!</h1></header>
      <nav>
        Menu:
        <ul>
          <li><a href="#bridges">Bridges</a></li>
          <li><a href="#tunnels">Tunnels</a></li>
          <li><a href="#interchanges">Interchanges (new!)</a></li>
        </ul>
      </nav>
      <article>
        <img src="road1.jpg">
        <img src="road2.jpg">
        <img src="road3.jpg">
        <img src="road4.jpg">
      </article>
      <footer>
        Credits:
        <ul>
          <li>Denys Nevozhai</li>
          <li>Edouard Ki</li>
          <li>Ishan @seefromthesky</li>
          <li>John O'Nolan</li>
        </ul>
        Source: <a href="https://unsplash.com">via Unsplash</a>
      </footer>
    </div>

  </body>
</html>

And here’s how it looks:

CSS Grid

Pretty crude styling, but we’ve got our web page laid out with a minimum of fuss.

Let’s see how it works.

We’ll start with the CSS for the container:

.container {
  display: grid;
  grid-template-columns: 0.25fr 1fr;
  grid-template-areas: "header header"
                       "nav body"
                       "footer footer";
  grid-gap: 1em;
}

We know about display: grid; and grid-template-columns already.

What about grid-template-areas? This is where we define how we want our page to look. What we’re really saying here is that the first row will be occupied by a header, which is identified like this later in the CSS:

header {
  justify-self: center;
  grid-area: header;
}

Note that it’s grid-area that identifies this rule for grid-template-areas, not the HTML element ‘header’.

For the second row of our grid, we’re saying that the first column will be occupied by nav, and the second column will be occupied by body. Here they are in the CSS:

nav {
  align-self: center;
  grid-area: nav;
}

article {
  grid-area: body;
  display: flex;
  flex-wrap: wrap;
}

Again, see how the grid-area style is used to link this rule back to grid-template-areas.

(Flex is used to arrange the images inside the article element. It doesn’t affect our grid layout).

Finally, both columns in the last row of our grid are occupied by the footer:

footer {
  justify-self: center;
  grid-area: footer;
}

One more thing:

That grid-gap value defines how much space should be between each row and column, 1em in this case. Space between rows and columns can be defined separately using grid-row-gap and grid-column-gap.

Centering Horizontally and Vertically in CSS Grid

You’ll notice that our header, nav, and footer use either align-self or justify-self:

header {
  justify-self: center;
  grid-area: header;
}

nav {
  align-self: center;
  grid-area: nav;
}

footer {
  justify-self: center;
  grid-area: footer;
}

The justify-self style aligns the element horizontally. In this case we want our header and footer to appear in the center of the grid.

align-self is used to arrange an element vertically.

If you want to know more about arranging elements within CSS Grid,  you should check this very comprehensive guide on box alignment in the CSS grid here.

Making the CSS Grid responsive

Let’s take a leaf out of Bootstrap’s book and go mobile first.

We’ll do this by moving our current .container style to a @media query at the end of our CSS:

@media (min-width: 768px) {
  .container {
    display: grid;
    grid-template-columns: 0.25fr 1fr;
    grid-template-areas: "header header"
                         "nav body"
                         "footer footer";
    grid-gap: 1em;
  }
}

And redefine our default .container style like this:

.container {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "header"
                       "nav"
                       "body"
                       "footer";
  grid-gap: 1em;
}

Which is to say we’ll have one column only, and our sections will just stack on top of each other:

CSS Grid Responsive Layout

 

Are you getting on the grid?

So that’s a super-quick introduction to the CSS Grid.

Even though we’ve barley scratched the surface, you’ve still learnt enough to go apply it to web pages right now.

In short, we’ve learnt how to:

  • How to use display: grid
  • How you can set up a very simple grid display
  • How you can make your grid responsive

And best of all we’ve done this with an incredibly small amount of CSS and without downloading a CSS framework.

Like this post, get social and share 🙂 I’ll be looking out for you!

 

By


Comments are closed.