When you add "display: grid" to a grid container, only the direct children become grid items and can then be placed on the grid that you have created. The children of these items display in normal flow.
You can "nest" grids by making a grid item a grid container. These grids however are independent of the parent grid and of each other, meaning that they do not take their track sizing from the parent grid. This makes it difficult to line nested grid items up with the main grid.
If you set the value "subgrid" on "grid-template-columns", "grid-template-rows" or both, instead of creating a new track listing the nested grid uses the tracks defined on the parent.
For example, if you use "grid-template-columns: subgrid" and the nested grid spans three column tracks of the parent, the nested grid will have three column tracks of the same size as the parent grid. Gaps are inherited but can also be overridden with a different "gap" value. Line names can be passed from the parent into the subgrid, and the subgrid can also declare its own line names.
The "item" is made into a grid (columns 2/7, rows 2/4), giving it column tracks that are a subgrid and defining rows as normal. As the item spans five column tracks (2/7), the subgrid has five column tracks. The "subitem" is placed on this grid.
The rows are NOT a subgrid and so behave as a nested grid does normally. The grid area on the parent expands to be large enough for this nested grid.
"Line numbering" restarts inside the subgrid: column line 1, when inside the subgrid, is the first line of the subgrid. The subgridded element DOESN'T inherit the line numbers of the parent grid. This means that you can safely lay out a component that may be placed in different positions on the main grid, knowing that the line numbers on the component will always be the same.
The setup is the same as the previous example, but "subgrid" is used as the value of "grid-template-rows", while defining explicit column tracks. The column tracks behave as a regular nested grid, but the rows are tied to the two tracks that the child spans.
A "gap", "column-gap", or "row-gap" specified on the parent will be passed into the subgrid, so that it will have the same spacing between tracks as the parent.
In some situations however you may wish the subgrid tracks to have a different gap or no gap. This can be achieved by using the gap-* properties on the grid container of the subgrid. In this example, the parent grid has a gap of 2vw for rows and columns. The subgrid has row-gap set to 0.
When using CSS grid "lines on the grid" can be named and then items can be positioned based on those names rather than the line number. The line names on the parent grid are passed into the subgrid, and they can be used to place items. In the example, lines on the parent are named "col-start" and "col-end" and then they are used to place the subitem.
Line names can also be specified on the subgrid. This is achieved by adding a list of line names enclosed in square brackets after the "subgrid" keyword. If there are four lines in the subgrid, to name them all you could use the syntax "grid-template-columns: subgrid [line1] [line2] [line3] [line4]". Lines specified on the subgrid are added to any lines specified on the parent so you can use either or both. To demonstrate this, one item in the example is positioned using the parent lines, and one using the subgrid lines.
Subgrids are an official substitute for nested grids to apply one grid inside another. It is scalable, responsive, and you don't need to adjust anything through extra code or Javascript. Being dependent on the parent container keeps it stuck to its assigned ratio and position.