CSS Grid — The Beginner’s Guide

By JavaScript Teacher

If you wish to support my work CSS Visual Dictionary is my book. All diagrams in this tutorial were influenced directly by the manuscript!

Getting started

You are probably already familiar with CSS’s box model for regular elements. Let’s begin with a similar “bird’s eye view” representation for CSS Grid:

CSS Grid’s anatomy is composed of the primary container which is just your standard <div> element that has a marginborder and padding. To make a parent CSS grid container out of any element, add display: grid to it. Grid’s items are children nested inside the parent container. They are usually defined as a list of elements that could represent a headersidebarfooter or similar website layout elements, depending on your application’s design.

In this case, there are 3 <div> items. The third one is stretched across 2 cells.

Notice that lines can be counted backwards, too, using the negative coordinate system.

The grid above is 5 by 4 cells in dimension. It is defined as follows:

div#grid {               /* This is our CSS grid parent container */
  display: grid;
  grid-template-columns: 100px 100px 100px 100px 100px; /* 5 cols */
  grid-template-rows:    100px 100px 100px 100px;       /* 4 rows */
}

The number of rows and columns is assumed implicitly by the number of values set.

In between each cell there is a line and an optional gap.

Rows and columns between the lines are referred to as grid’s tracks.

There are always [track + 1lines per dimension.

Therefore, 5 columns will have 6 lines whereas 4 rows will have 5 lines.

In the following example, there are 7 columns and only 1 row:

Some of the first things you will notice about the CSS grid behavior.

The first important thing you will notice about CSS grid is that the outer linesare not affected by gap size. Only inner lines. We will take a deep dive into this a bit later in this tutorial when we look at fractional (fr) units.

The CSS grid is bi-directional.

Its items can flow either horizontally (column) or vertically (row). Set the value with the grid-auto-flow property.

It works kind of like Flex:

Using grid-auto-flow: row or grid-auto-flow: column to determine flow direction of the grid’s items.

Think about the grid in this abstract way:

Okay — so we’ve got the basic idea of how it works.

Item placement

The creative part comes in when you are faced with the problem of actually juggling the item placements to create a sensible application layout. CSS grid offers several properties to accomplish just that. We’ll take a look at them in the next section in this tutorial in just a moment.

Let’s cement our knowledge so far by looking at these examples:

I only used two <div> elements for the items. Hence, the grid above.

Implicit and Explicit Content Placement

But what happens if we add one more item to the list?

Adding item 3 to the same layout will automatically extend it (blue item.)

This new spacing is created automatically by copying values from first row.

Let’s add Item 4 shall we?

And again, our CSS grid has made a decision to stretch Item 4 across the remaining space on second row. This is because grid-template-rows specified enough space only for 1 row.

The rest are automatic.

Placement of blue items is not explicitly specified by you. This is implicit(automatic) placement. They kind of just fall into that space.

Explicit Content Placement

This is just what you would expect from grid cells if you set custom values for all items on the list:

Basically, you can gain control over the space on all consecutive rows by adding more values to the grid-template-rows property. Notice the items are no longer implicit here. You defined them to be exact. (25px and 75px)

Automatic Spacing

CSS grid offers a few properties to automatically stretch its cells across a variable/unknown amount of space. Here are the key examples for both the column and row auto flow cases:

The bottom example demonstrates the usage of the auto keyword. This just means that the cell will stretch to fill up however much space is left in the parent container after it has already been populated by explicitly placed items.

CSS Grid Gaps

When you’re talking about CSS grid, you can’t escape talking about gaps. Gaps are the horizontal and vertical spaces between grid cells.

Gaps are controlled using the grid-column-gap and grid-row-gapproperties:

You can use varying gaps in both dimensions. This can be useful for creating video or image galleries:

Gaps across dimensions (columns and rows) can differ in size. But gap size is specified once for all gaps in the grid in a given dimension. As you can see here — gaps of varying size within the same dimension are not allowed:

I really wish varying size gaps were possible. I can see how this could actually be useful. Some suggest to use empty tracks in order to achieve a similareffect.

FR units (Fractional Units)

Fractional (fr) units are unique to CSS grid.

fractional unit allocates relative to all other elements in the parent:

The behavior changes but 1fr remains the same regardless whenever different values are used. Fractional units work similarly to % values, but they are easier and more intuitive to divide space with:

Behavior of fractional units (fr unit) changes based on all values provided in either dimension.

In this example, only column-wise behavior is shown for simplicity’s sake. But it works the same for rows, too. Simply use the grid-template-rows property.

Fractional Units And Their Relationship To Gaps

Space defined using fractional units changes based on gaps. The same 1frwithin the same parent will shrink to a smaller size when gaps are added:

Here we added gaps to cells specified using fr units.

As you can see, this gives you a pretty good set of properties to space content basically in any way you wish without worrying about pixel values.

These new dynamics render pixel-perfect design as a thing of the past. We will now think about layout design using the intuitive approach!

Finally, to give you a better idea of using non-whole fractional units, here is a fun grid I created. You can specify them using floating point numbers too:

Content Placement

We’ve just dissected the CSS grid anatomy. Hopefully you get a better idea of how CSS grid structures content. But now we need to get creative and actually place some items inside it. How it’s done might modify the default behavior of the CSS grid. We’ll explore how this happens in this section.

To arrange your items across cells or template areas on the grid, you will refer to them by the lines between cells. Not <table>-like spans.

CSS grid does allow using spans for determining the width and height of the content area (in cell space) just like tables. We’ll explore that in just a bit. But you still can and probably should specify the starting cell using line numbersor named lines (more on this in a bit.) This depends on your preference.

Cell Content Spanning

As far as content placement across multiple cells goes, the most obvious and tempting thing is cell spanning.

You can span an item across multiple cells.

Important: Spanning changes the location of the surrounding items.

Spanning using grid-column and grid-row

Using the grid-column and grid-row properties on the item element itself:

The blue items changed location after making Item 7 span across multiple cells. And orange items were bumped down a row.

There is also another way of doing the same thing…

Spanning using grid-column-start

With grid-column-endgrid-row-start and grid-row-end you can specify actual starting and ending points across which you want to span cell content.

I removed the items past 15 (orange ones) because we no longer need them:

Type these properties directly into the item you wish to be affected by them.

Stretching content across the column and row lines works in both directions.

min-content and max-content

The values min-content and max-content are supplied to grid-template-columns or grid-template-rows properties just like any other size-related value (for example px1fr, etc.)

Let’s take a look at this specimen above. It is our starting point. We’ll change things around a bit to see how the min/max values affect cells.

Let’s see what type of results will be produced if we switch one of the columns to min-content and max-content:

With one-word text there’s no difference between the results observed whether we use min-content or max-content. Here it is because hello is a single word. Its min and max values are exactly the same.

But things get interesting with more complex text. The following example will demonstrate the basic idea behind min-content and max-content:

Here min-content used the longest word in the sentence (stranger) as a base width.

When using max-content, the entire text string with spaces filled the space.

But what happens if we apply min-content or max-content to all cells?

I noticed that by default the text was centered whenever I used min-content on it although text-align: center was not set on the item.

Images and max-content

I placed the image of this blue rose into the cell.

And just as expected, the grid expanded to allocate enough space:

When I explicitly set the width of the image to 50% just to see what happens, CSS Grid still kept cell width to 100% of the image, but displayed the image at 50% width (as expected) and auto-centered it horizontally within the cell.

Both text and images (or any content) will be automatically centered within CSS Grid’s cells by default.

Content Positioning

Up until this point, we’ve talked about Grid’s structure in general.

In the next section, we’ll take a look at how to achieve “multi-directional” float inside cells. We won’t be using the float property here, of course.

Multi-directional 360° float

I don’t think CSS Grid specification calls it that. But, indeed it is possible to create exactly that… a 360-degree floating behavior.

This works on both inline and blocking elements! And I think this is my favorite feature from the entire CSS Grid’s set of abilities.

All nine combinations are possible using align-self and justify-self properties.

They are explained below.

Align Self (align-self)

This property helps you position content vertically.

Use align-self: start to align content to the upper edge of the cell.

Use align-self: center to align content to its vertical middle.

Use align-self: end to align content to the bottom of the cell.

Justify Self (justify-self)

This property helps you position content horizontally.

Use justify-self: start to align content to the left edge of the cell.

Use justify-self: center to align content to its horizontal middle.

Use justify-self: end to align content to the right edge of the cell.

You can use any of the nine justify-self x align-self combinations to align anything anywhere, creating a multi-directional float.

Template Areas

Template areas are defined using the grid-template-areas property.

Note: template areas for each row are enclosed in double quotes — but of course you can use single quotes too.

Within those quotes, each column is separated by space.

In this example, I simply explained how to name areas. To take real advantage of template areas, you need to categorize rectangular blocks of cells by the same name. Tetris blocks are not allowed. You can only use rectangles:

Here Left is one area spanning three cells down. CSS Grid automatically treats it as a single block. The same goes for Right. In this simple example I created two columns. But you get the idea. Block out larger areas by naming them.

To place an item into that area, simply add grid-area: TemplateName. In this case it is grid-area: Left or grid-area: Right.

Template area names cannot use spaces. I used dashes here.

Practical Example of CSS Grid Template Areas

We now understand how to block out rectangular areas. Let’s take a look at a potentially real-world scenario. Here I’ll demonstrate the creation of a simple site.

I blocked out a very simple website layout with two sidebars and a headerand footer area. The main area is in the center occupying 3 x 2 cell space:

We only need 5 items here. Add any more and they would be pushed outside of the main grid area into implicit cells. It is fine if you keep track of them.

Just make sure to always keep your areas square or rectangular. No Tetris.

Naming Lines

There is one last thing I wanted to mention before we reach the end of this tutorial: naming CSS grid lines.

Instead of always referring to lines by their number, you can also name them. This way, they will be easy to remember for stretching items across multiple cells. Numbers can get tedious.

Below is a representation of what it looks like.

Use square brackets to name your lines. Then use these names when specifying the length your items need to span across using the / slash.

In Conclusion

CSS Grid is a comprehensive subject. Hence, this is not a complete CSS Grid tutorial on how to build actual CSS layouts. I simply used one example for each separate part as a starting point for someone new to the grid.

Hopefully, the information I provided here was insightful and inspired interest in building websites using CSS Grid.

CSS Grid isn’t just an HTML element. It’s an entire system for building responsive websites and web applications.

Its properties and values describe the conglomerate of techniques learned by industry veterans in over a decade building sites using common HTML tags.


Follow Me For Weekly Freemium On Social Networks

You can, on Twitter for weekend PDF giveaways.
Follow me on Instagram for a quick hit of JavaScript.
You can follow me on Facebook for free coding stuff.
If you wish to support my work CSS Visual Dictionary is my book.
Many diagrams in this tutorial were influenced directly by the manuscript!

Leave a Reply