_k

CSS Grid Layout

CSS Grid Layout is a new way to layout things on the web. In opposite to floating, which wasn’t intended to be used to layout a whole page, Grid Layout is developed to be used as exactly that. Which means you can wave goodby to Frameworks and divs with row and col classes.

In opposite to flexbox, which is one dimensional, Grid Layout generates a two dimensional grid. This makes them perfect companions and solves problems like columns with equal heights.

Because all of this isn’t ready yet, i’m using the Firefox developer edition, in which this feature already is enabled.

Let’s see how it works by building something like this:

The finished product

At first we need some html to start with.

<div class="container">
  <div class="item">#1</div>
  <div class="item">#2</div>
  <div class="item">#3</div>
  <div class="item">#4</div>
</div>
.container {
  display: grid;
}

By setting the display property, all children of this container become items of this grid system. Because there isn’t a template defined yet, all items are just stacked on top of each other.

To differentiate the items, i've applied colors to each one and set a small padding.

Not very impressive, but we can do something about it. By using the two new properties grid-template-columns and grid-template-rows we can define a simple Template with two horizontal and three vertical grid tracks.

.container {
  grid-template-rows: [ra] 1fr [rb] 1fr [rc] 1fr [rd];
  grid-template-columns: [ca] 1fr [cb] 1fr [cc];
}

Now we got three rows with two columns each. Because we only got four items, they are evenly distributed into the first four grid areas. The last two are left empty, because nothing is there to fill them altough, the space is kept free, because we defined all grid areas to be equal in width and height.

The new unit fr (flexible length) defines the amount of free space an item can take up in the grid. It acts like the number in the flex-grow property which tells the browser how the free space should be distributed. Because all areas have a value of 1 they are all the same size. You don’t need to use the fr Unit but can also stick to more traditional ones like em, %, or px.

The values in the brackets will name the grid lines, which gives you another way to position the items on the grid. You can name the lines whatever you want, i’ve decided to use short names like to keep the code short. A grid area is always enclosed by four of these lines. This means an area must be a rectangle and can’t be L shaped like your favorite Tetris block.

To make position even more easy it’s possible to name the grid areas. Just add the grid-template property to the container, and describe the grid by naming the areas. To make the first row an big area we must name both columns in the first row the same.

.container {
  grid-template-areas: "top top"
                       "lefttop right"
                       "leftbottom right";
}

The layout is now automatically made up by the browser, because we haven’t told the items where they should be placed on the grid. Let’s start by making the first item full width. You can also specify how the auto layout should layout the items if you don’t need to position each item individually, but thats a thing for another post.

.item:nth-child(1) {
  grid-column: 1/span 2;
}

This command tells the grid to take the first box and set the starting line to line 1. The span 2 means that the box will take the width of two columns in our grid. Insted of working with numbers we could’ve also set ca/cc to use the named grid lines.

But as we saw earlier we also defined names for the grid areas. Let’s use the top one to position our item.

.item:nth-child(1) {
  grid-area: top;
}

To get our desired layout we now need to position item 2 and 3 to the left.

.item:nth-child(2) {
  grid-area: lefttop;
}
.item:nth-child(3) {
  grid-row: 3/4;
  grid-column: 1/2;
}

Like grid-column, grid-row sets the top of item 3 to the third grid line and the bottom to the fourth line. We can leave this property for item#2 out because the auto layout already positions the item at the right place.

The last thing to do is to tell item#4 to fill up two rows of the grid. Like with the column you can tell an item to span multiple rows.

.item:nth-child(4) {
  grid-row: 2/span 2;
  grid-column: 2/3;
}

Now the items are in the right size and order, but are sticking together. We can fix this by defining the gutter of the grid.

.container {
  padding: 15px;
  grid-row-gap: 15px;
  grid-column-gap: 15px;
}
An outer padding keeps the items from sticking on the sides of the window.

To finish things up i added a border radius and background image to the items. Because they behave like normal block elements, you can style them as you like. You can find the final code on codepen.

Browser suppport

The specification currently is a Candidate Recommendation which means that you need to enable it before using it.

Can I Use css-grid? Data on support for the css-grid feature across the major browsers from caniuse.com.

At the time of writing, the next version of all major desktop browsers will support CSS Grid Layout. Except for Internet Explorer and Edge which implement an older version of the specs which is not compatible with the new one.

CSS Grid Layout will initially ship without subgrid support, altough the property is in the specs. This means we only can use grid on direct childs of the container and not inside the items, but have to redefine a grid for the item again. Hopefully it will make it’s way to the browsers fast after CSS Grid Layout is released.

Further reading