DEV Community

Cover image for CSS Grid: nested grid
Mateusz Kirmuć
Mateusz Kirmuć

Posted on

CSS Grid: nested grid

Hello. In today's article, I want to talk about nested grids. I will show you how to create grids inside the grid which can be very helpful in creating complex layouts. Let’s get started.

This article is part of my CSS Grid introduction series. If you want to check out my previous posts, here you can find the whole table of contents.


Nested grid.

In my previous article, I talked about grid items. It’s important to remember that any content inside a grid item is by default positioned according to normal flow. You can change that, and one of the methods is to define a given grid item as a nested grid container.

The way to create a nested grid is similar to creating a regular grid. To define a new nested grid you have to use the same display: grid property and grid track properties inside the grid item CSS rule.

<div class="container">
  <div class="grid-item nested-grid">
  </div>
</div>

.container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
}

.grid-item.nested-grid {
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  grid-template-columns: repeat(4, 1fr);
}
Enter fullscreen mode Exit fullscreen mode

Image description

Remember that no element of the nested grid is inherited from the parent grid. This includes grid lines (both names and ids) and gaps between grid tracks. You have to define those on your own.

.container {
  display: grid;
  grid-template-columns: [first-col] 1fr [second-col] 1fr [third-col];
  grid-template-rows: [first-row] 1fr [second-row] 1fr [third-row];
  gap: 15px 2rem;
}

.grid-item.nested-grid {
  display: grid;
  grid-template-columns: [col-1] 1fr [col-2] 1fr [col-3] 1fr [col-4];
  grid-template-rows: [row-1] 1fr [row-2] 1fr [row-3] 1fr [row-4];
}
Enter fullscreen mode Exit fullscreen mode

Image description

The nested grid can influence the size of the parent grid track that contains it. This happens when the parent grid track is flexible enough to allow it — its size should be defined using auto, fr, min-content, max-content, or fit-content.

.container {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-columns: auto 1fr 1fr;
}

.grid-item.nested-grid {
  display: grid;
  grid-template-columns: 1.5em 200px;
  grid-template-rows: 150px 4rem;
}
Enter fullscreen mode Exit fullscreen mode

Image description

Finally, a nested grid container allows the creation of implicit grid tracks. Implicit grid tracks are tracks created automatically by the auto-placement algorithm. This happens when the required definition of grid tracks is missing — for example, when there are more elements to be placed than cells in the grid.

<div class="container">
  <div class="grid-item nested-grid">
    <div>1</div>
    <div>2</div>
    <div>3</div>
  </div>
</div>

.container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
}

.grid-item.nested-grid {
  display: grid;
  grid-template-rows: 1fr;
  grid-template-columns: 1fr 1fr;
}
Enter fullscreen mode Exit fullscreen mode

Image description

Notice that the nested grid should have only one row, according to its definition. The auto-placement algorithm creates an additional, implicit row to create the required place for a third grid item.

I will discuss more about implicit tracks and auto-placement algorithm in one of my feature articles.

Subgrid value.

As a bonus, I want to tell you about some very promising feature improving the creation of layouts using a nested grid. This feature included in Level 2 of the CSS Grid Layout specification is implemented currently only in Firefox 71 (and up). That’s why here I want to make a preview of all changes that come along with it.

The mentioned feature is an additional ‘subgrid’ value that may be used with grid-template-rows/grid-template-columns properties.

.grid-item.nested-grid {
  grid-template-rows: subgrid;
  grid-template-columns: subgrid;
}
Enter fullscreen mode Exit fullscreen mode

Using subgrid value, the nested grid will inherit grid tracks definition as well as grid-line names, and track gaps from the parent grid in a given dimension. Grid-lines numbers however won’t be inherited.

.container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: [col-1] 1fr [col-2] 1fr [col-3] 1fr [col-4];
}

.grid-item.nested-grid {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: subgrid; 
  ...
}
Enter fullscreen mode Exit fullscreen mode

Image description

Notice how the nested grid ‘inherits’ vertical tracks from the parent grid, as well as the gaps between them and line names.

Grid gaps can be overwritten inside the definition of the nested grid.

.container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr); 
  column-gap: 20px;
}

.grid-item.nested-grid {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: subgrid; 
  column-gap: 50px; 
  ...
}
Enter fullscreen mode Exit fullscreen mode

Image description

You can also specify your own grid line names by putting them in square brackets after the subgrid value.

.container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: [col-1] 1fr [col-2] 1fr [col-3] 1fr [col-4];
}

.grid-item.nested-grid {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: subgrid [sub-col-1] [sub-col-2] [sub-col-3]; 
  ...
}
Enter fullscreen mode Exit fullscreen mode

Image description

Keep in mind that instead of regular nested grid behavior, the subgrid will prevent the creation of implicit grid tracks in a given dimension.

<div class="container">
  <div class="grid-item nested-grid">
    <div>1</div>
    <div>2</div>
    <div>3</div>
  </div>
</div>

.container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  grid-template-columns: repeat(3, 1fr);
}

.grid-item.nested-grid {
  display: grid;
  grid-template-rows: subgrid;
  grid-template-columns: 1fr; 
  ...
}
Enter fullscreen mode Exit fullscreen mode

Image description

As you can see, an additional track for the third element won’t be created, which results in the overlapping of two elements.


Thank you for reading this short article. If you want to read more content like this you can follow my dev.to or twitter account. Also, feel free to give me any form of feedback. I'd love to read any comments from you. See you soon in my next article!


PS. If you would like to support my work, I will be grateful for a cup of coffee. Thank you. ❤️

Buy Me A Coffee

Top comments (0)