Exploring CSS grids and their awesomeness
Tags: css, grid, tutorial
Published: 2017-11-08 10:41:00

---
title: "Exploring CSS grids and their awesomeness"
published: true
description: "A tutorial on CSS grid layout by Aurel Kurtula"
cover_image: https://thepracticaldev.s3.amazonaws.com/i/5esgxsz2l8n6x45iizng.png
tags: [css, grid, tutorial]
---

This tutorial is about CSS grids. I write it after reading the mozilla documentation and building something which I think turned out pretty cool, all be it quick and rushed in places. 

The plan was to take few days and create something useful with grids and then write a proper introductory tutorial on how I went about creating such a website, but that has to take a back seat for now because I just want to share this with you. And it will be a good document for when I decide to write a follow up.

Here is what I created:

![](https://thepracticaldev.s3.amazonaws.com/i/trwiiazxeiud8dfo9rk5.png)

Doesn't that look cool? I tried doing this with floats before and I never got a satisfying result, it needed a lot of hacking and the structure was to be just so!

With grids it was really easy to implement. 

## Let's start creating the grid

First we will get the basics down. We need 20 divs in the html file and we'll need to give them the basic styles.

Here's the html

```html
<div id="wrap">
    <div class="box" id="id1"><h1>1</h1></div>
    <div class="box" id="id2"><h1>2</h1></div>
    <!-- ...20 divs -->
</div>
```

(If you use emmet you could type `#wrap>div.box#id$*20>h1{$}` and hit enter.)

Now let's add some starter css.

```css
@import url('https://fonts.googleapis.com/css?family=Lovers+Quarrel');
*{margin: 0; padding: 0;}

.box{
  height: 35vh;
  display: block;
  text-align: center;
  font-family: Lovers Quarrel;
  font-size: 4rem;
  color: white;
  position: relative;
}
.box h1{
  position: absolute;
  top: 40%;
  left: 40%;
}
#id1, #id10, #id12, #id16{ background-color: #A5CB57;}
#id2, #id9, #id13, #id17{ background-color: #F77775;}
#id3, #id8, #id11, #id18{ background-color: #9CD3CD;}
#id4, #id7, #id14, #id19{ background-color: #181818;}
#id5, #id6, #id15, #id20{ background-color: #F8A880;}
```

First line, we import a google font - just because we can, so why not! The next line resets padding and margins of all the elements. 

Then give the `.box` some height, use the font we imported, make the font size big. Centre the `h1` tag in the middle of the box. 

The end result is this:

![image](https://thepracticaldev.s3.amazonaws.com/i/1ume7a8ztqbuk8b45ybw.png)

Now, pay attention because this is really quick and easy!

```css
#wrap{
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
```   

BOOM! We just created a grid with two columns. Our boxes just flow from left to right each being 50% wide.

The `grid-template-columns` is interesting and the `fr` unit even more so. We could use any unit in there. The logical alternative might be `%`:

```cs
grid-template-columns: 50% 50%;
grid-template-columns: 200px 200px; 
```

If we use the first line from the above, the result would be the same - create 2 columns, each being 50% wide. The second line creates two columns but each would be `200px` wide - no practical reason to do so, but you could.

Instead, we should use `fr` units. They are new and from the [spec](https://www.w3.org/TR/css3-grid-layout/#fr-unit) we learn that

> A flexible length or `<flex>` is a dimension with the `fr` unit, which represents a fraction of the free space in the grid container.

So by using two `1fr` we are dividing the container in two columns.

Whilst my mission here is to create a photo/quote grid, and practical uses will be covered some other time, a website with two sidebars and content in the middle, might be styled using the following grid template:

```css
grid-template-columns: 1fr 3fr 1fr
```

For our purpose we need a grid with 6 columns!

```css
#wrap{
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
}
```

Clearly writing and reading 6 units is horrible and prone to error, so we are able to use the repeat function in css.


```css
#wrap{
  width: 100%;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
}
```

Here is the end result of our grid. 

![image](https://thepracticaldev.s3.amazonaws.com/i/3bokp2nqb9cyh7pjcttg.png)

I should have used more colors, but you can see six grids. I feel like even if we stop here, it's just beautiful. 

Grids give us the ability to pick any of our boxes and enlarge them, whilst other boxes would just wrap around the remaining space. 

```css
#id1 {
  grid-column-start: 1;
  grid-column-end: 3;
}
```

In plain english that doesn't make sense! We want our div to take up two columns - so why end at three? Well, if you remove the `background-color` and add a `border-left` and `border-right` you'll see seven lines. So if you are to draw a box from line one to line three, you'd be using two columns. 

![img](https://thepracticaldev.s3.amazonaws.com/i/b2w6vckxfj0je3o39yfo.png)

Finally let's do the same for rows. We want that box to be a proper square, we have it occupying two columns, it's only proper it should take over two rows as well, let's update the above

```css
#id1 {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 3;
  height: 100%;
}
```

Exactly the same thing just from top to bottom.

I find it interesting that we need the height! If we do not add that in, the div would still act as if it's taking up one row, whilst the grid has carved the space for two (try leaving the hight property out to see what I mean)! 

Let's do the same thing to another box

```css
#id5{
  grid-column-start: 5;
  grid-column-end: 7;
  grid-row-start:1;
  grid-row-end:  3;
  height: 100%;
}
```

We are still creating a box to take two columns and two rows but now we want it to start from line 5 (5th column) and end at line 7 (6th column). 

You could take the 20th box and have it display on the first row. **At the end of the day that's going to be one of it's powers, to truly treat each section of the website as an isolated component.**

## Lets span some boxes

So far, we took one of the boxes (a div) and placed it exactly where we wanted (for example, from line 1 to line three of the grid). We didn't really care where the original position was. Again, as this is very important, we could take any of the boxes, and have it placed anywhere in the grid, other elements would just move. 

There is another way though. Using `span` we could just span a box from where ever it is to where ever we want it to be. 

```css
#id15{
  grid-column-end: span 3;
  grid-row-end:span 2;
  height: 100%;
}
```

We are spanning the box with id `id15` three columns to the left and two rows down, from where ever it might be. Note that this time the number `3` represents three columns and `2` represents two rows.

## A dilemma I had which I haven't investigated yet.

We can span to the right but not to the left! `grid-column-end: span 3` widens the element from left to right. If the element is on the far right,is there a way to span to the left?

At the moment, if we do this, we get an empty grid cell:

```
#id12{
  grid-column-end: span 3;
  grid-row-end:span 2;
  height: 100%;
}
```

The end result being:

![image](https://thepracticaldev.s3.amazonaws.com/i/uadt2s31kg8sdjsawt15.png)

In a normal design, where we would want to know where everything is at, this might be no issue, but it's something I noticed and, whilst I could talk myself into thinking this is a good thing, I can't say I didn't google it as a bug!

## Conclusion

It was fun playing with this grid. Here is the [demo of the photo-grid](https://aurel-84637.netlify.com/). The photographs are from [unsplash.com](http://unsplash.com) and the quotes are from the one and only, Ralph Waldo Emerson. 

As I'll try to do with most of the tutorials I'll write, the demonstrations are always going to have something extra, that extra code is simply for my amusement and adds nothing to the core concepts I explore. In this case: few block quotes and the use of css pseudo-elements are nothing worth going off topic about.

I tried the demo on my mac and it works on all three browsers that I have (chrome, firefox, and safari). I tried it on a windows laptop and the grid didn't work at all, but [caniuse website](https://caniuse.com/#feat=css-grid) tells you more about the support (maybe the computer I tried had older browser versions)

*Note, I did not use media queries so the demo is only useful on a big screen. The next tutorial on grids will include everything*