This article has been translated to French by Pierre Choffé on La Cascade.

We’re 5 days away from the stable release of Firefox 52. Do you know what this means? This means in 5 days, CSS Grids will be supported, And Chrome 57 will follow close behind on March 14, then Safari 10.1 and hopefully Edge, before the end of 2017.

I’m so excited.

Can you tell how excited I am? Maybe some emojis can help convey the message. 🎊🙆🎉💃

My deep dive into CSS grid

Remember when Rachel Andrew answered the question of whether we should use Flexbox or Grid? No? Watch the video then.

Flexbox for 1 dimensional layout. CSS Grid is for 2 dimensional layout.
— Rachel Andrew

I’m sure smarter people than me have this figured out by now but until my recent month-long torrid affair with CSS Grid, I didn’t realise how well Flexbox and Grid went together. It was like peanut butter and jelly, or apples and cinnamon, or bacon and eggs. Oh my gosh, I’m getting hungry.

Some of you may have noticed that I’ve started contributing to Codrops CSS Reference. It’s seriously one of the best things that happened to me in 2016, I might write about it. Or not. We’ll see. One of the pending entries on the list was for CSS Grid. Before I started writing that entry, I had only played around a little bit with Grid, and built a prototype version of Penang Hokkien using Grid just to see if it would play better with vertical writing-mode than Flexbox.

Then I sat down and wrote the entry.

3 weeks later, I felt like I had fused with a max-level Metal Cactuar (that’s a Final Fantasy Brave Exvius reference, I can’t help it, Final Fantasy is a thing in my life 🤷), in other words, it was a major levelling-up. I spent a lot of time with the actual specification, all 86 pages of it (according to my print settings).

There were also the CSS Grid articles written by Manuel Rego Casasnovas which really dive into specific features of Grid, like positioned items, grid layout placement and auto-placement. And Rachel Andrew’s Box Alignment Cheatsheet was such a life-saver, because another resource I was using had the axes mixed up, making me extremely confused for a few days.

Here’s my tip. When trying to learn any CSS property, have a blank HTML template on hand so you can play around in a clean sandbox environment. This was especially useful for a new feature like Grid. I know we have Codepen and all, but I like a blank slate for distraction-free experimentation.

Examples and demos

As I worked my way through the properties, I started off building very basic grids, just to see how each property value worked. If you’ve seen the syntax for grid-template-rows in the specification, you’ll realise that this was not a trivial task. Grid itself is not hard to learn. But because it was built to be very flexible and powerful, you’ll need to spend a bit more time to get to know Grid.

A few of those basic grids grew into proper demos. Some demos were inspired by conversations with people from the CSS Layout Club. I’m also auditing Ideas from the History of Graphic Design on Coursera, so plenty of inspiration from there too (last week was Bauhaus week ❤️).

I came across this page from Malerei, Fotografie, Film by László Moholy-Nagy which was laid out in a grid and the first thought that popped into my mind was, that can be done in CSS…I think. Well, only one way to find out.

Page 126 of Malerei, Fotografie, Film
Page 126 of Malerei, Fotografie, Film

Bauhaus in my browser

Here’s my process. I drew grid lines over the image in Sketch so I could figure out how many columns I needed. For this case, it worked out to be 1 large column followed by 5 narrower columns of equal width and I let the browser figure out the row heights.

.grid {
  display: grid;
  grid-template-columns: 30% 9% 9% 9% 9% 9%;
  justify-content: center; /* to justify the grid in the middle of the container */
}

After that, it was a whole bunch of placement code with the grid-row and grid-column properties. But if you look at the original image again, you’ll see that the content in each grid cell is have their own alignment. Like the first cell’s contents are flush to the right, the word in the second cell is flush left and bottom, and so on.

My first instinct, since I got this whole box alignment thing all figured now, was to apply justify-self and align-self where necessary to adjust the content positions within each grid cell. Nice try, close but no cigar. The issue with doing that is these 2 properties affect the amount of space occupied by the grid cell.

The Bauhaus design has a lot of striking black borders around each grid cell. The border property applies onto the grid item. Any grid alignment property other than stretch will make the size of the grid item fit to its contents. Any borders applied to grid items naturally fit the grid item’s contents, so I couldn’t do that, it messed up the design.

These are not the borders you're looking for
Diagram of grid items fitting to content size

Flexbox to the rescue

By default, all grid items behave as if their alignment had been set to stretch on either axis. So I left that alone, to allow the grid to actually look like a grid. Instead, I applied display: flex to the grid item, allowing me to use flex alignment properties applied on the flex container to position my grid item’s content. 😎

That's more like it
Positioned content within grid cell
.grid__item:nth-child(5) {
  grid-row: 3 / 5;
  border-right: 1em solid;
  padding: 1em;
  
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
}

The code looks something like that, but my point is, this is a great technique for building layouts. Grid for the grand scheme of things, and Flexbox for specific adjustments. Here’s the Codepen link if anybody is interested in the final result.

See the Pen Malerei, Fotografie, Film (pg. 126) by Chen Hui Jing (@huijing) on CodePen.

Bonus segment: CSS shapes

Other than the 2 photographs on the page, everything else is CSS, which means the arrow and the gear are actually styled divs. I love making CSS shapes, single div, if possible. You just need a few handy properties to help you, box-shadow, border and pseudo-elements.

Arrow

Arrows are pretty straight-forward. You just need 1 extra pseudo-element for the arrow-head. Make the div the body of the arrow, and give it position: relative so you can absolutely position the arrow head relative to the body. The arrow head is a triangle, which can be made using the border trick.

.arrow {
  width: 0.5em;
  height: 65%;
  background-color: #000;
  position: relative;
  
  &::after {
    display: block;
    content: '';
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: -1em;
    border-style: solid;
    border-width: 1em 1em 0 1em;
    border-color: #000 transparent transparent transparent;
  }
}

Gear

This was a little bit more tricky. The gear body itself is a circle, which is border-radius: 50%, but the gear teeth will need more trickery. I couldn’t do it with a single div this time (though if anyone can, please tell me how). I had an additional inner div to help with the gear teeth. The good thing is that all the gear teeth are the same shape, so the box-shadow trick can be used here.

.gear {
  height: 5em;
  width: 5em;
  background-color: #000;
  border-radius: 50%;
  position: relative;

  &::before,
  &::after {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: block;
    content: '';
  }
  
  &::before {
    height: 3em;
    width: 1em;
    box-shadow: 0em -3em 0em 0em #000, 0em 3em 0 0em #000;
  }
  
  &::after {
    height: 1em;
    width: 3em;
    box-shadow: 3em 0 0em 0em #000, -3em 0 0 0em #000;
  }
}

The gear body and the 4 compass direction gear teeth were made with a single div and its 2 corresponding pseudo-elements. For the other 4 gear teeth, I used the inner div with pseudo-elements then rotated the box-shadows. I still need to figure out the transform-origin issue because I think it looks a bit asymmetrical at the moment.

.inner-gear {
  height: 2em;
  width: 2em;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: #e1e1d5;
  
  &::before,
  &::after {
    position: absolute;
    display: block;
    content: '';
  }
  
  &::before {
    height: 3em;
    width: 1em;
    box-shadow: 0em -3em 0em 0em #000, 0em 3em 0 0em #000;
    transform: rotate(45deg);
    transform-origin: (75% 75%);
  }
  
  &::after {
    height: 1em;
    width: 3em;
    box-shadow: 3em 0 0em 0em #000, -3em 0 0 0em #000;
    transform: rotate(45deg);
    transform-origin: (25% 75%);
  }
}

Wrapping up

I find Grid really awesome, and I’m obviously not the only person who thinks so. Jen Simmons has compiled a list of really good Grid resources so check out Learn CSS Grid and try building something with Grid. You won’t regret it. 😁