Command Shift

Layout - Grid

Please note! These pages are a lot to take in! Don't worry too much if you don't grasp it straight away. Flexbox and Grid are quite advanced CSS. It's not required that you use it in all your projects, so have a read, have a practice, and have a look at some of the resources at the end when you're ready. You've got this!

Let's learn about CSS Grid!

Definition

CSS Grid Layout, which is commonly called Grid, or CSS Grid, is a two-dimensional (rows vs columns) grid-based system that, at the time of its introduction, completely changed the way we design and build user interfaces.

Before you start asking which one, between Flexbox and Grid, is better, be aware that they're complementary and tend to work really well together.

Explicit vs Implicit

You can explicitly define the number of rows and columns of your layout, when you know beforehand the result you want to achieve and how many elements you're attempting to lay out. Or, you can also let the browser (implicit) define the number or size of rows or columns.

You can also place items in a particular spot of your layout or, once again, let the browser place each item using Grid's auto-placement algorithm.

As with Flexbox, you apply grid to the parent, as a display value, and its children will become grid-items. Do you remember this previous HTML snippet?

<div class="parent">
  <div class="child">A</div>
  <div class="child">B</div>
  <div class="child">C</div>
  <div class="child">D</div>
</div>

So, to create a grid layout:

.parent {
  display: grid; /* The div .parent is now a grid container. */
}
 
.child {
  /* All of these items are now grid items. */
}

You can then define a template for both the columns and rows.

Columns & Rows

Take a look at the image below:

Grid can be, sort of, summarised in tracks, cells, rows and columns:

  • Tracks divide the container into cells. A grid of 4x4 cells is created by 5x5 tracks.
  • One grid area is built with, at least, one cell.
  • Cells can have different sizes.
  • Grid areas should be meaningful and logically group content/features.

Let's investigate it further:

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

In the example above, we're defining the composition of our layout by stating that it will have 3 equal columns (fr stands for fraction). The template of the rows is implicitly defined by the number of elements, which are auto positioned by the browser. If we would like to explicitly define it, we would use a similar property - grid-template-rows.

Gaps

You can specify the size of the tracks, which is very useful to space things out:

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  column-gap: 10px;
  row-gap: 15px;
 
  /* Or, simplifying it, with row-gap first: */
  grid-gap: 15px 10px;
}

You can also drop the prefix grid- and leave the key as gap, only.

Justify-Items & Align-Items/ Place-Items

The way to align your items as a group is somewhat similar to Flexbox. It revolves pretty much around these 3 properties: justify-items, align-items and place-items.

  • justify-items aligns them along the horizontal axis.
  • align-items aligns them along the vertical axis.

Both of these can take on the values of start (of the grid cell), end (of the grid cell), center (of the grid cell) and stretch (across the whole grid cell).

  • place-items is the shorthand way of writing these, with align-items coming first.
.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  column-gap: 10px;
  row-gap: 15px;
 
  justify-items: start;
  align-items: end;
 
  // Virtually the same as:
  place-items: end start;
}

It can also be a quick multi-directional centering:

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  column-gap: 10px;
  row-gap: 15px;
 
  justify-items: center;
  align-items: center;
 
  // Virtually the same as:
  place-items: center;
}

The grid-items will also have its own set of properties:

Grid-column & Grid-row

grid-column and grid-row determine the item's location within the grid by referring to specific grid lines - emphasis on the word line!

It takes the value of start-line / end-line, separated by a slash(/):

.child {
  grid-column: 1 / 3;
  grid-row: 1 / span 3;
}

Looking at the example above:

  • The child element will be place from line 1 to line 3, so it should occupy exactly 2 columns. And, horizontally-wise, it should start in line 2 and span across 4 lines, so it occupies 3 rows.

If you're like many of us and like things on pen&paper, design a grid of 10x10 on a piece of paper, and assign numbers to all of the lines - both columns and rows - and try to draw a rectangle that occupies the cells stated above:

Justify-Self / Align-self / Place-Self

You can think of justify-self, align-self and place-self in the same way of justify-items, align-items and place-items, with place-self being the shorthand way of writing the first two, where align-self comes first.

It also takes values of start, end, center, stretch.

.child {
  justify-self: center;
  align-self: start;
 
  // Virtually the same as:
  place-self: start center;
}

As it happens with the parent, it can be used as a quick multi-directional centering.


Template Areas

A grid can also be defined by a template which is built upon named areas. Let's say we want to create a template that fits our sidebar, a header, a footer and a main area for content:

.parent {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main main"
    "sidebar main main"
    "footer footer footer";
}

So, our template will have 4 rows and 3 columns, and whichever elements we display in these areas, will occupy the corresponding grid-cells.

.header {
  grid-area: header;
}
 
.sidebar {
  grid-area: sidebar;
}
 
.main {
  grid-area: main;
}
 
.footer {
  grid-area: footer;
}

Does it make sense?

You can think of it as a shorter shorthand for grid-row and grid-column.

MinMax

Grid also offers a sizing function - minmax(), which is kind of self-explanatory. As you might have guessed, it sets a minimum and a maximum value for what the length is able to be, which is very useful when you want to be very restrictive on how much a certain grid-cell is able to shrink.

.parent {
  display: grid;
  grid-template-columns: minmax(500px, 1fr);
}

In the example above, we're stating that in our grid, we'll have a column that can't shrink beyond 500px.

Once you get comfortable around this function, you'll realise that it's an amazing way of making your layouts responsive across different platforms without recurring too much to media queries - a topic we'll cover next.

Repeat()

The other function worth noting is the repeat() one, which you'll definitely grow to love. Imagine you want to create a grid with 10 columns, all equally distributed across the available space:

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

Fun, right? What if we're talking about 20 columns?

A much nicer way of doing it is by using the repeat, function:

.parent {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
}

And you can also combine both functions:

.parent {
  display: grid;
  grid-template-columns: repeat(10, minmax(100px, 1fr));
}

(Just don't forget any (), otherwise your css will be broken!)

And that's all you need to know about CSS Grid (not really). There's so much more to it - remember when we said that Grid is super powerful and widely used for massive layouts!

Congratulations for coming this far and taking loads of notes!


Practice

CSS Grid Garden

In terms of approach, this game is very similar to the flexbox one. The idea is for you to write the correct grid property that moves the water block to where your carrots are placed (just like Farmville, but for nerds). The CSS editor will always have some built-in grid in the #garden element. Take your time to observe it before you write your property.

We've also prepared 2 codepens for you:

Take a look at their HTML & CSS and try to understand how the layout is being built, using all of the knowledge you've just acquired. Feel free to change properties around (they won't be saved once you leave/refresh your browser tab).

Finally, here's an absolute bible on CSS Grid, written by some of the best frontend developers.

On this page