How to Efficiently Master the CSS Grid in a Jiffy

How to Efficiently Master the CSS Grid — in a Jiffy

Learn the 20% you need for 80% efficiency with CSS Grid.

Ohans Emmanuel
Flexbox and Grid
Published in
18 min readJul 7, 2017

--

Introduction

This is NOT the article to learn “everything” about the css grid.

On the contrary, the target audience is people who want results quickly, and be productive while at it.

In the four parts of this article, I will show you the 20% you need for 80% efficiency with the CSS Grid layout.

Let’s dig in!

Why just 20%?

Where possible, a programmer seeks efficiency — the supposed lazy way out.

The CSS Grid layout is complex. In my opinion, more complex than Flexbox. (mehn, it took me weeks to figure out flexbox)
Not so because it is “difficult” but the CSS Grid has 18 new properties plus other concepts you’ve never heard of anywhere else in CSS.

So, do you need all of these new properties now? Right now?

No, you don’t!

Just learn the bit to get you results now. You can go ahead to learn the other properties later. This is my definition of “efficiency with the CSS Grid layout”

1. What is the CSS Grid Layout ?

If you’re new to layouts in CSS, the CSS Grid layout may seem strange to you.

Have you heard of Flexbox?

I like to view the CSS Grid layout as an older sibling (or parent) of Flexbox.

Handling Layouts in CSS have been difficult and crappy. Flexbox brought a bit of fresh air — but the CSS Grid is even better.

What we’ll Build.

You will learn to apply your 20% knowledge to building a clone of a responsive music app layout.

a responsive music app, catty music

Part 1: The 10% you Need to Know — Basic Terminologies

Let’s take a look at the first things you absolutely have to know.

What is a Grid Container?

Every website, or application layout you make (or have seen) is essentially, boxes placed within certain defined boundaries.

gif by chris bannister

In very simple terms, a grid is just “lines”. Horizontal and vertical lines that define the placement of other design elements.

You’ll be familiar with this if you use design software such as adobe photoshop or sketch.

In the context of the CSS Grid layout, A Grid container is the parent that contains all the items in the grid. The Grid container defines the initial placement of the grid lines, both vertical and horizontal.

What is a Grid Line?

Assume for a bit that you have a fully laid out grid like this:

supposed grid layout

The layout comprises a grid container with a number of perfectly laid out grid items (children elements within the grid)

a bit of explanation

Grid lines are the horizontal and vertical lines that divide the grid.

What is a Grid Cell?

A Grid cell is the smallest unit of area in a grid layout. It is any space bounded by four grid lines.

The “small boxes” of grid items may be referred to as grid cells.

Grid Area

A grid area may be as small as the area contained within a grid cell (shown above). It may also be as large as all the cells within the grid.

In the image below, the area covered by the four cells is a grid area.

What is a Grid Track

I don’t like very technical definitions. So, a grid track may be seen as a fancy name for columns and (or) rows. It is the space between any two grid lines.

The image below show example grid tracks.

grid tracks

So, we’ve got the first part sorted out.

Part 2: The “Other” 10% you Need to Know — CSS Grid, Baby steps.

Now that you understand the basic terminologies, like an adventurous kid, let’s get kicking!

How do you Define a Grid?

Just like Flexbox, everything begins with a one-liner. display: grid or display:inline-grid for an inline version.

For example, to make a certain div a grid container, do this:

div {
display: grid;
}

How do You Create Columns and Rows?

A grid without columns and rows is kinda pointless. To create columns and rows within a grid container, you use these two new css properties: grid-template-columns and grid-template-rows.

So how do you use these? Pretty simple.

grid-template-columns defines the placement of the columns. grid-template-rows defines the placement of the rows.

You pass in length values into these properties, and they create row and column tracks within the grid container.

See an example:

grid-template-columns: 100px 200px 300px

This will create 3 new columns within the grid container. The first with a length of 100px, the other, 200px and the last, 300px.

grid-template-columns: 100px 200px 300px

grid-template-rows: 100px 200px 300px

This will create 3 new rows within the grid container. The extents are shown below

grid-template-rows: 100px 200px 300px

Now put these together, and you get a full grid — with rows and column defined.

grid-template-columns: 100px 200px 300px
grid-template-rows: 100px 200px 300px

Part 3: Time to Code — CSS Grid, Hands-on

Now let’s take baby steps to building a clone of the famous music app, catty music 😁

For speedy development, I would be using Codepen. Spin up a new project, and let’s get cracking.

How to Create the Basic Grid Setup for Catty Music

I believe you have a basic codepen project up and running now.

We will kick off with a very basic html document.

<body>
<aside></aside>
<main></main>
<footer></footer>
</body>

There’s a bit of foresight involved in choosing this structure. You’ll understand very soon.

Now style the document.

body {
display: grid;
min-height: 100%
}

This will kick off the grid formatting context by making the body a grid-container

Now we can go on to define the rows and columns structure within the grid.

How to create the Rows and Columns for Catty Music

Creating the rows and columns is pretty easy.

The final design we are gunning for is this:

final layout we seek.

However, the initial grid setup we need is a grid of 2 rows and 2 columns.

initial grid setup

Here are a few things to note about this Grid setup

Columns:

  1. The first column must have a fixed width — say, 50px
  2. The second column must fill the remaining width in the grid.

Rows:

3. The second row must have a fixed height — say, 100px

4. The first row must also fill the remaining height within the grid.

The lay-man’s solution.

If you’re NOT very experienced with CSS, you’re likely to write this:

body {
...
grid-template-rows: 100% 100px;
grid-template-columns: 50px 100%;
}

The problem with this is that you have accidentally created a grid whose width and height is a total of 100% + 50px / 100% + 100px

We want a total width and height of exactly 100% So this approach is wrong.

The “smart ” person’s solution.

If you’ve got some experience with CSS under your belt, then you’re likely to do something much more smarter. Like this:

body {
...
grid-template-rows: calc(100% - 100px) 100px;
grid-template-columns: 50px calc(100%-50px)

This is pretty smart. But it’s got one problem — it isn’t very maintainable.

For example, If for some reasons you have to change any of the the fixed widths, then you must always change the calc definition.

The efficient Solution

Luckily, CSS Grid has a new unit that solves our problem elegantly. The fractional unit (fr)

The fractional unit solves the problem of automatically distributing space.

If you have three grid columns aligned as shown below, the fractional unit will automatically distribute the space equally.

If for some reason you add more elements — no worries. The fr unit will equally redistribute the space .

Finally, if you have a fixed width element, then you can take up the remaining space with the fr unit.

Here’s what I mean:

body {
...
grid-template-rows: 1fr 100px;
grid-template-columns: 50px 1fr;

And that is it — done!

If you’re still confused with fr unit, please check out, the CSS Fractional Unit (Fr) In Approachable, plain Language. It only takes 3 minutes.

Naming and Positioning Items by Grid Areas

We explicitly created the grid system. Now, let’s put it to use.

The goal of this section is to learn to position grid items using grid areas.

If you recall from an earlier section, a grid area is any area bounded by 4 grid lines.

The “small boxes” of grid items may be referred to as grid cells.

How do you start using grid areas?

The logical place to begin is naming grid areas.

Let me explain that.

Consider the code block below:

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

3 divs — simple. By the way, It is semantically better to use aside main and footer tags. I’ll just keep things simple.

Now see this:

.main {
grid-area: content;
}
.footer {
grid-area: footer;
}
.aside {
grid-area: sidebar;
}

What is happening there?

If you write a bit of Javascript, or any programming language, then the concepts of variables isn’t new to you.

In Javascript, we could say:

var gridArea = "content"

What is done above is, save the string content into the variable gridArea

What the CSS declarations above does is quite similar.

Every grid item can be assigned to an area within the grid container. Read that again.

Every grid item can be assigned to an area within the grid container

However, before doing that, it is imperative to attach the grid items to an area name. Like you assign variables in Javascript — sort of.

.main {
grid-area: content;
}
.footer {
grid-area: footer;
}
.aside {
grid-area: sidebar;
}

The code block above says, let the .main class have an area name of content. Let the .footer class have an area name of footer. Finally, let the aside class have a grid name of sidebar

Now the grid items have all been assigned area names.

In programming, variables are set to be used elsewhere. Now let’s make use of the grid area names.

Grid area placement

A young man has a well baked cake. He has 3 children asking to give them some portions. Ideally, who shares the cake?

The young man!

The young man cuts out the areas and gives them to his children.

yummy!

Here’s why I told that sweet story.

Like the cake, the entire grid area is owned by who?

The grid container!

Like the young man, the grid container has 3 children too .aside .main and .footer Now the grid container gets to choose how the entire area portions are shared.

One more thing.

Because the children all have names, the young man may say, “hey Brian, here’s your portion”, or “hey Emma, have this”

It is easy to identify who owns what portion of the cake, by assigning the portions to a named individual. I have no cure for you if you live in a country where people go without names 😁

The grid items all have names! We did so using the grid-area property.

Now, let’s share the cake!

The grid-template-areas property

Now the grid container must share the “cake”. Assign what area portions goes to who.

There are many ways to do what I am about to explain to you, but the grid-template-areas property is the easiest to reason about. It is the bit you need to know for efficiency.

How does the grid-template-areas property work?

Take a look at the code below:

body {
grid-template-areas: "sidebar content"
"footer footer";
}

😳 what the heck is that ?

That my dear, is the grid-template-areas property in action. There’s no need to get overwhelmed. In this section, I will explain how it works — in clear terms.

The grid-template-areas property (what a long property name) provides a very visual structure of the grid.

Take a look at the code again:

body {
...
grid-template-areas: "sidebar content"
"footer footer";
}

Note that the entries in the property value are the names of the grid items!

sidebar content and footer refer to the names of the grid items. The declaration above has succesfully shared the area with respect to the names of the grid items — brilliant!

The image above will help you understand how the area portions have been split.

The footer takes the entire bottom area. The sidebar and content take first and second top areas respectively.

Awesome!

At this point here’s what we have:

body {
display: grid;
grid-template-columns: 40px 1fr;
grid-template-rows: 1fr 90px;
grid-template-areas: "sidebar content"
"footer footer";
}

The result of that is this:

I have added colors for visual aid. The red section represents the footer, the other two sections, the .main section and .sidebar.

Let’s Get Responsive — Redefining Grid Areas with Media Queries

gif by Muharrem Senyil

The Grids areas you create within the parent grid container are not set in stone. The grid areas can be changed based off of the screen size of the user’s device.

The Image below shows what we aim to achieve on mobile displays.

Catty Music, on mobile

For our specific use-case we will do some refactoring for a mobile first approach.

Mobile first is simply making your default styles those for mobile devices. Then you may go ahead to make changes for larger displays via media queries.

Tweak the current code you have now. Wrap the grid defining bit in a media query.

Like this:

@media only screen and (min-width: 600px) {
body {
grid-template-columns: 120px 1fr;
grid-template-areas: "sidebar content"
"footer footer";
}
}

You should leave the defaults excluded from the media query

body {
display: grid;
grid-template-rows: 1fr 50px;
}

Why do I have grid-template-rows: 1fr 50px excluded from the media query?

This is because both mobile and desktop screens will have the same row definition. 2 rows.

However, on desktop devices, there’s a sidebar. The sidebar accounts for the 120px in the grid-template-columns definition. Howbeit, the sidebar is non-existent on mobile devices.

Thus, we will redefine the grid-template-column declaration for mobile.

Now for mobile devices, we will leave this as the default styling. i.e not wrapped in any media query.

body {
grid-template-areas: "content"
"footer"

Pretty simple?

Let me explain.

The default flow (direction) of a Grid

The code block for mobile displays is easy.

body {
grid-template-areas: "content"
"footer"

However, note that there was no need to specify grid-template-columns

By default, a grid will align it’s children along rows.

So, the declaration above will align content along a row, and footer along another.

Below is the result of that — the sidebar hidden on mobile.

With the initial hurdle of understanding how grids work, and setting up a responsive grid, let’s finish up the app layout!

Placing Content within the Grid.

At the end of this section, we would have the Music app layout completed. The focus being, how to place and align content within grids.

Let’s get started.

1. The Sidebar

This looks like the easiest to start with. Let’s go for it.

The sidebar consists of 8 icons equally spaced out vertically accross the entire length of the sidebar.

Insert the icons, like this:

<div class="aside">
<i class="fa fa-bars"></i>
<i class="fa fa-home"></i>
<i class="fa fa-search"></i>
<i class="fa fa-volume-up"></i>
<i class="fa fa-user"></i>
<i class="fa fa-spotify"></i>
<i class="fa fa-cog"></i>
<i class="fa fa-soundcloud"></i>
</div>

Below is the result of that:

Also, hide the icons when on mobile. Show them when the app is visited on a larger screen. This is the mobile first approach.


.aside i {
display: none;
}
@media only screen and (min-width:600px) {
.aside i {
display: block;
}
}

The icons are displayed, but poorly aligned.

Aligning the icons

The i tags are inline elements — which explains why every 2 icons sit on one line.

Let’s fix the arrangement.

Grid items can be grids themselves. Why not

Step 1: Make the Sidebar a Grid Container

This will give access to using the grid’s alignment features.

Since the sidebar is only seen on larger screens, do not forget to wrap this in the media query.

@media only screen and (min-width:600px) {

.aside {
display: grid;
}

.aside i {
border: 1px solid red;
}
}

I have gone ahead to add borders to each icon — so they are visually distinguishable.

What’s happening there?

We have NOT set up any rows or columns within the sidebar. But we have the icons laid out fairly well. The grid auto placement algorithm has set in.

This is got to do with the default placement of items in a grid — along a row. Also, the grid items are arranged to take up the space of the grid container, as needed.

Here comes the sweet sauce.

A grid may align it’s items using any of justify-items or align-items.

justify-items will align the items along the row axis. In most cases, row is pretty much synonymous with the horizontal direction.

align-items will align the items along the column axis. In most cases, column is also synonymous with the vertical direction.

Apply this to the sidebar, and we have perfectly laid out icons.

.aside {
...
justify-items: center;
align-items: center;
}

Still confused, watch the changes in the sidebar items as I type.

Now we have perfectly laid out icons within the sidebar.

A few other values justify-items and align-items can take include:

  • stretch
  • start
  • end
  • center

If you’ve worked with Flexbox, these should be familiar.

We’ll proceed to placing more content into the current design.

Target the main section, the dark blue section in the image above. Place two div within:

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

NB:

  1. main__header will house the music art and playbacks:
.main__header

2. main__body will house the details:

.main__body

In this section we will focus on main__header

First off, add the required html

<div class="main__header">
<div class="img">
<img src="http://bit.ly/2sc2NJd"/>
</div>
<section class="details">
<div>
<p>CattyBoard Top 100 Single Charts (11.06.36)</p>
<p class="sm--hide">Unknown Artist</p>
<p class="sm--hide">2016 . Charts . 100 songs</p>
</div>
<div>
<i class="fa fa-play"> &nbsp;Play all</i>
<i class="fa fa-plus"> &nbsp;Add to</i>
<i class="fa fa-ellipsis-h">&nbsp;&nbsp;More</i>
</div>
</section>
</div>

Note the way the document is structured.

main__header has two direct children. A div that contains an image, and a section that contains album details, .details

The result of the addition above is this rather ugly image:

incomplete header

Let’s make this pretty.

What we need is a grid that aligns its children appropriately.

Let’s make use of your new knowledge of grid areas.

First step, define the grid areas:

.main__header > .img {
grid-area: img;
}
.main__header > .details {
grid-area: dtls;
}

The div containing the image has been named img The section containing the album details has been named dtls

Now, define the grid itself:

.main__header {
display: grid;
grid-template-areas: "img"
"dtls";
}

.main__header sets a grid formatting context. The areas have also been aligned to stack vertically on another. imgfirst, then dtls

This is because we are working with a mobile first approach. Good.

At this point, nothing much’s changed.

I have included borders and made the text whitish for visual aid.

This is NOT the view we want on mobile.

For mobile screens, the items should be aligned to the center. Fix that.

@media screen and (max-width: 600px) {
.main__header {
justify-items: center;
}
}

Now the grid items will be positioned to the center of the grid (along the row)

Make the texts in .detailsalign to the center:

@media screen and (max-width: 600px) {
.main__header > .details {
text-align: center;
}
}

Pretty close to the end goal. Just a few more tweaks.

The paragraphs with the texts, unknown artist, and 2016 . Charts. 100 songs. should be hidden on mobile. The image should be smaller too.

@media screen and (max-width: 600px) {
.sm--hide {
display: none;
}
.img > img {
width: 150px
}
}

Every class .sm--hide will be hidden on mobile. Just add this class to the desired element.

Here’s how:

<p class="sm--hide">Unknown Artist</p>
<p class="sm--hide">2016 . Charts . 100 songs</p>

And we have this:

Having sorted out the view on mobile, let’s fix that for larger screens.

Back to the parent grid.

For larger screens, we need a 2 column grid. The areas should be split like this:

@media only screen and (min-width:600px) {
.main__header {
grid-template-columns: 250px 1fr;
grid-template-areas: "img dtls"
}
}

I’m sure you understand what’s going on there.

The grid has been redefined to have two columns. One fixed at 250px and the other to fill the remaining space.

https://codepen.io/ohansemmanuel/pen/gReOQJ?editors=1100

Our current progress lives here.

Part 4: Making CSS Grid work with Flexbox

In this part, you’ll learn to make Flexbox and Grid work together — peacefully.

These two technologies have changed how layouts in CSS are treated. It is efficient ot use both technologies where possible.

Let’s delve in.

For the section housing the music details, we will use flexbox.

How do you know where to use Flexbox?

As a general rule of thumb, it is appropriate to use Grid to layout the overall page layout, and Flexbox for inner UI components.

A grid item can be a flex container. A flex item can also be a grid container. The latter is frequently used though.

I assume you have a good grasp of flexbox.

As always, begin with the html

Below is a div, with a list of songs. The list of songs have paragraphs containing the name of the song, artiste, duration of the song and “catty cloud sync”.

<div class="main__body">
<div>
<p>1. One Dance</p>
<p>Crake feat CatKid &amp; Cyla</p>
<p>2:54</p>
<p><span>CATTY CLOUD SYNC</span></p>
</div>
<div>
<p>2. Panda</p>
<p>Cattee</p>
<p>4:06</p>
<p><span>CATTY CLOUD SYNC</span></p>
</div>
<div>
<p>3. Can't Stop the Feeling!</p>
<p>Catin Cimberlake</p>
<p>3:56</p>
<p><span>CATTY CLOUD SYNC</span></p>
</div>
<div>
<p>4. Work From Home</p>
<p>Cat Harmony feat Colla</p>
<p>3:34</p>
<p><span>CATTY CLOUD SYNC</span></p>
</div>
</div>

Here’s what we’ve got:

main__body is a grid item. We could make it a flex container if that was useful.

For our use case, each direct div child of main__body needs to be flex container. This is the divthat contains the name of the song, artiste, duration of the song and “catty cloud sync”.

.main__body > div {
display:flex;
}

Now split the width amongst the child elements:

.main__body > div p{
flex: 0 0 25%;
}
https://codepen.io/ohansemmanuel/full/pwLEBL/

You’ll agree with me that at this point, the essentials of the layout is done. Yes, ✅

However, I have gone ahead to make a few cosmetic changes.

You may view the result of that here

You’ll notice that I have left the footer blank. That’s supposed to be an exercise for you. My advice is to use flexbox. This will strengthen your understanding of getting both technologies to work together. Go ahead and make the grid item, footer a flex container.

If you need some cues, check out catty music built completely with flexbox.

With just a few grid properties, you have built a real world layout. That’s pretty impressive. You’ve also learned the invaluable skill of making the CSS Grid layout work with Flexbox too.

Want to become Pro?

Download my free CSS Grid cheat sheet, and also get two quality interactive Flexbox courses for free!

Get the Free CSS Grid Cheat sheet + Two Quality Flexbox Courses for free!

Get them now

--

--

Ohans Emmanuel
Flexbox and Grid

Authored 5 books and counting. This one will teach you intermediate to advanced Typescript in React: https://shrtm.nu/kqjM