Let’s talk about CSS Grid

Let’s talk about CSS Grid

It seems like everywhere I’ve been lurking lately including the office has had people talk about CSS grid and what it means for developers and how we build websites. I sat down this week to really try and understand CSS grid, what it does and how it works. I’m a huge fan of Flexbox so I initially I didn’t care as much. I think now that I’m spending more time looking at it I think CSS grid coupled with Flexbox is going to be the way to go in the future and put us all out of a job, especially with AI and Machine Learning building websites for us.

Something I thoroughly enjoyed when learning about CSS grid was just how easy it is. There’s a lot of space to play within it and a lot of flexibility that let’s us get what we want. In some ways it feels a lot like building a website with tables, which while feeling dirty in the beginning makes a lot of sense for the very box based layouts we mostly create on the web today.

You can see the finished Grid demo over at this link: https://codepen.io/Haydos585/pen/RpXPZa

As I write this, CSS grid and it’s related properties are supported in IE 11, Chrome 57, Firefox 52 and Edge 14. According to caniuse.com IE and Edge both have support for an older spec. Microsoft seems to be doing pretty well with Edge so I’m sure it will be coming along shortly. Grid is also supported across Chrome for Android and Safari for iOS. It’s a reasonably available tool to use if you’re working with late browser versions but I’d hold off before using it for any client work and stick with Flexbox or good old floats.

Getting started with Grid is easy. All we need to do is add a “display” property to our container element. In my case, a div with container as a class.

.container {
  display: grid;
}

Instantly we’re given the layout for a grid. This isn’t enough to really get going though so we’ll add some more properties:

.container {
 display: grid;
 grid-template-rows: 200px min-content min-content 1fr;
 grid-template-columns: 1fr 300px;
}

What happens here is we create four grid-template-rows. The first has a height of 200 pixels, the second and third only go as high as the content inside them, the minimum height to fit the content. The fourth row will be 2 fractions high. A fraction is an even height or width based on the rest of the content in the container.

Next we create two columns. The first column is 1 fraction wide, the second column is 300 pixels wide. The container stretches to 100% of the parent, in our case the body. The browser here works out the 300 pixels first and then says fill the rest of the space with the other column.

We can set as many rows and columns as we want for the grid, which is great and something we’ll use later when we assign children to the rows and columns. You might be wondering right now whether you’re going to have to define each column and row individually. Nope. If we have a piece of CSS that looks like:

grid-template-rows 200px min-content min-content 1fr;

We can make it simpler by using the repeat() function. We can now make our code look like this:

grid-template-rows: 200px repeat(2, min-content) 1fr;

The repeat function does basically what you’d expect it to. You pass in the amount of times you want to repeat something and the value you want to put in there as the second parameter. The default for grid items is min-content but if you’re using fractions or a unit like pixels or REMs then you can save time with repeat!

We’re now ready to start adding in our child elements and assigning them their columns and rows. First let’s create some basic HTML structure for our page.

<html>
  <head>
    <title>CSS Grid</title>
    <style>...</style>
  </head>
  <body>
    <div class="container">
      <div class="banner">
        
      </div>

      <div class="navigation">
        Navigation
      </div>

      <div class="main">
        main
      </div>

      <div class="search">
        Search
      </div>

      <div class="sidebar-items">
        Sidebar items
      </div>

      <div class="footer">
        footer
      </div>
    </div>
  </body>
</html>

This structure is super simple and is kept that simple for instructional purposes. For the sake of the demo assume I’ll be putting all CSS between the style tags.

Right off the bat you can see we’ve got a container element that will be the base for our grid. We’ve already done the CSS for this one. Next we have a pretty generic looking HTML page with navigation, a main content area, search component, sidebar items and a footer. You can swap these divs out with whatever your favourite HTML5 elements are and you can name the classes whatever works best for your use case as long as you update the CSS too. You already know this. You’re smart.

First I’ll share with you the completed CSS and then go through and describe what we do:

body {
 margin: 0;
}
div {
 border: 1px solid black;
 padding: 10px;
}
.container {
 border: none;
 display: grid;
 grid-template-rows: 200px repeat(2, min-content) 1fr;
 grid-template-columns: 1fr 300px;
 padding: 0;
}

.banner {
 background-image: url('https://placehold.it/1422x200');
 background-color: #ee0044;
 grid-row: 1;
 grid-column: 1 / span 2;
 padding: 0;
}

.banner img {
 width: 100%;
}

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

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

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

.extra {
 grid-row: 4;
 grid-column: 2;
}

.footer {
 grid-row: 5;
 grid-column: 1 / span 2;
}

There’s some setup stuff like removing margin on the body element, I also set some padding and a border on all divs on the page to show how the grid sets itself up.

The banner class has a background image from https://placehold.it and a background color too. This is not what you’re here for though. We use the grid-row property and give it a value of 1. This puts it into the first row of the parent grid, which we set up before. grid-column: 1 / span 2 is a bit trickier but does the same stuff. We put the banner class into the first column of the parent grid and tell it to span across 2 columns so that it goes full width. If we had 3 columns in our grid we could use 1 / span 3 and it would work the same!

Amazing

Next we do the same for navigation, search, main, extra and footer. This is the power of the CSS grid we can assign our elements to their rows and columns and it just works. There’s an interesting line of CSS in the .main class that works similarly to banner, navigation and footer except for rows. Because we want to have 2 rows in our sidebar and we don’t want our footer to have a sidebar lets make our main div to be vertically aligned with our sidebar. We do that with the same syntax as columns except now it’s for rows:

grid-row: 3 / span 2;

You’re not required to assign rows and columns to each of your items. This could get really tedious if you have a lot of elements. When setting up your grid try to think in broad strokes of where you components sit within the grid.

If you don’t assign rows and columns the browser will do it’s best to assign them in the order they appear in the document.

Super simple. This is the basics for CSS grid and we’re not done yet. If you’ve made it this far I think you should take a break and play around with what you have. Change some of the values for grids and rows and see what happens.

Naming rows and columns

Manually incrementing all your rows and columns can become pretty unmanagable especially if you want to add another row or column in later on. Everytime you add a new column you’ll need to redefine every other column and row. If you use the code we’ve used above you’ll run into exactly this problem. Let’s hop into 2017 and use names for things. Our new CSS will look like this:

grid-template-rows: [banner] 200px
  [navigation]&nbsp;min-content
  [main] min-content
  [sidebar] min-content
  [footer] 1fr;
 grid-template-columns: [left] 1fr [right] 300px;

It’s a pretty simple syntax and easy to get into. We define our rows and columns inside square brackets and the value on the right. That’s it. There’s really nothing else to it. To apply our brand new named rows and columns we use code that looks like this:

grid-row: banner;

We now have CSS that looks like this:

.container {
 border: none;
 display: grid;
 grid-template-rows: [banner] 200px
 [navigation] min-content
 [main] min-content
 [sidebar] min-content
 [footer] 1fr;
 grid-template-columns: [left] 1fr [right] 300px;
 padding: 0;
}

.banner {
 background-image: url('https://placehold.it/1422x200');
 background-color: #ee0044;
 grid-row: banner;
 grid-column: left / span 2;
 padding: 0;
}

.navigation {
 grid-row: navigation;
 grid-column: left / span 2;
}

.search {
 grid-row: main;
 grid-column: right;
}

.main {
 grid-row: main / span 2;
 grid-column: left;
}

.sidebar-items {
 grid-row: sidebar;
 grid-column: right;
}

.footer {
 grid-row: footer;
 grid-column: left / span 2;
}

What next?

Well, not much. CSS Grid isn’t widely available yet, I had to update Chrome before I could write this article. Firefox, Chrome and Edge will all have Grid support available soon. Combined with Flexbox it’s going to be a seriously powerful combination that will cut down huge amounts of development time.

Currently there’s a few problems that people have found when working with CSS Grid. One of the most common complaints I came across when writing this post is that we’re unable to define a page level grid. We’re only able to define parent component grids and each additional component would need it’s own grid. This might be a good place to use SASS includes and mixins if they’re in your toolkit. The W3C is currently working on this and we might have a solution one day but these things move slowly.

Get excited about Grid layouts, they’re going to change how we build websites. Using CSS Grid and Flexbox is going to change things for the better. It might even put us all out of a job!

Resources

I had a ton of help writing this article from a few articles listed below. There’s not a lot of information about CSS Grid yet and due to the lack of browser support we can’t really use it in production but there are some good articles and developer guides to CSS Grid that should get you excited for the future:

About Nick

Melbourne based web developer that loves Laravel, Ruby on Rails, Phoenix/Elixir, Writing, Travel, Jiu-Jitsu and Starcraft.

www ·

Leave a Reply

Your email address will not be published.