CSS Aesthetics with Subgrid

A lot has been said and written about CSS grids. CSS grid provided a much-needed solution to web typography and layouts. A personal favorite of many, it created a more robust system of designing web layouts by allowing grid layouts in two dimensions, rows, and columns.

As impressive as the CSS grid is, it still has a few limitations and some aspects that could improve. One of the avid limitations on the CSS grid is the nesting within the grid itself.
CSS grid, especially grid areas, could define a general layout, allowing major elements like <header>, <nav>, <article>, <section> and <footer> to have a particular blueprint. But it made no provisions for outlines within each of these elements. To define tracks, developers then must rely on nesting grids within a parent grid.

The major problem with this method was inheritance. The nested grid had no relationship with the parent grid, and it acts independently on its own. The grid adjusts based on its relative position and not the parent grid.
Another issue this raised was responsiveness and aesthetics issues. Nested grids were not responsive to parent grids, and so they could sometimes overflow parent boundaries and change the topography of the web page. To change this, we need a new property.

Here is a simple example of nesting in a CSS grid:

.container{ 
  display: grid; 
  grid-template-columns: 1fr 1fr 1fr 1fr; 
  grid-template-rows: 300px; 
  grid-gap: 10px;    
} 
.three{ 
  display: grid; 
  grid-template-columns: 1fr 1fr 1fr; 
  grid-template-rows: 100px; 
} 
.card{ 
  background-color: rgb(235, 182, 102); 
} 
.subcard{ 
  border: 2px solid rgb(116, 95, 95); 
  background-color: rgb(252, 158, 7); 
}
<div class="container">
  <div class="card"> 
    <h1>This is a Card One</h1> 
  </div> 

  <div class="card">  
    <h1>This is card two</h1> 
  </div>

  <div class="card three"> 
    <div class="subcard">
      <h3>Subcard one</h3>
    </div>
    <div class="subcard">
      <h3>Subcard two</h3>
    </div> 
    <div class="subcard">
      <h3>Subcard three</h3>
    </div> 
    <h1> Card three</h1> 
  </div> 

  <div class="card"> 
    <h1>This is card four</h1> 
  </div> 
</div>

Card three has three nested grids within it. Rather than have it inherit the values of the parent container, we must define its own specific values. It is not so noticeable now, but when we add content to the grids, we will notice how different the nested grid is from the parent grid.

We will be looking at that shortly.

Come in Subgrid

CSS Subgrid is a property or a grid defined within another grid, which we refer to as a parent grid. It works just like nesting, but unlike nesting, the Subgrid maintains a relationship with the parent grid and inherits the formatting and values of the parent grid.

We define a Subgrid by using the keyword 'subgrid'.

Subgrid works on both axes, grid-template-rows, and grid-template-columns. It can also be defined individually for each axis.

Subgrid on Rows

One way to test subgrids on the row axis is to align properties to fit the same aesthetic throughout. Because the row-axis relates to height, we will try to align our elements with the same height using subgrids.

.container { 
  display: grid; 
  grid-template-columns: repeat(4, 1fr); 
  grid-template-rows: repeat(4, auto); 
  gap: 1em; 
  padding: 1em; 
} 
h2{ 
  background-color: pink; 
  padding: 0.5em; 
} 
.subgrid{ 
  border: 2px ridge grey; 
  box-shadow: 4px 4px 0 0 #222; 
}
img{ 
  width: 100%; 
  height: 300px; 
} 
footer{ 
  text-align: center; 
  background-color: coral; 
  padding: 8px; 
  color: white; 
} 
p { 
  padding: 0 10px; 
  font-size: 18px; 
}
<body>
  <div class="container"> 
    <div class="subgrid"> 
      <h2>Header 1</h2> 
      <img src="image 1.jpg" alt="image 1"> 
      <p>This is a paragraph but i don't think it should be one regardless of what you say </p> 
      <footer>Read more</footer> 
    </div> 
    <div class="subgrid"> 
      <h2>Header 2 but a with a longer header to make it noticeable</h2> 
      <img src="image 2.jpg" alt="image 2">
      <p>A really short paragraph.</p> 
      <footer>Read more</footer> 
    </div> 
    <div class="subgrid"> 
      <h2>Header 3</h2> 
      <img src="image 3.jpg" alt="image 3">
      <p>Here, i am testing out what could potentially be a longer paragraph because i want to show how this affects the layout of the card itself. Do you see it yet?</p> 
      <footer>Read more</footer> 
    </div> 
    <div class="subgrid"> 
      <h2>Header 4</h2> 
      <img src="image 4.jpg" alt="image 4"> 
      <p>What kind of paragraph should this be if not a sweet header paragraph 4</p> 
      <footer>Read more</footer> 
    </div> 
  </div> 
</body>

This code gives us an uneven alignment.

Subgrid Result 1 - Uneven Alignment

From the image, we can see the headers, text, and footers are scattered. For Header 2, as the text gets longer, it pushes down and becomes misaligned.
Header 3 has a longer text that pushes the footer further down. Using ‘subgrid’ on the subgrid class, we can create a perfectly aligned card, regardless of text length.

.subgrid{ 
  grid-template-rows: subgrid; 
  display: grid; 
  grid-row: span 4; 
  border: 2px ridge grey; 
  box-shadow: 4px 4px 0 0 #222; 
}

Update the subgrid formatting to include the grid and subgrid properties and the span of the grid. You get this:

Subgrid Result 1 - Proper Alignment

Subgrid on Columns

Subgrid on columns works just as well as Subgrid on rows. Only in columns are we dealing with the grid’s width.
In this example, we will create a nested grid and assign the tracks to be positioned.

body {
  margin: 10px; 
} 
.container { 
  display: grid; 
  grid-gap: 1em; 
  grid-template-columns: 100px 200px 1fr 2fr; 
  grid-template-rows: repeat(3,minmax(100px,auto)); 
  background-color: #fff; 
  color: rgb(131, 81, 81); 
} 
.card { 
  background-color: rgb(131, 81, 81); 
  color: #fff; 
  border-radius: 5px; 
  padding: 20px; 
  font-size: 15px; 
} 
.one { 
  grid-column: 1/3; 
} 
.two { 
  grid-column: 3/5 ; 
} 
.three { 
  grid-column: 1; 
  grid-row: 2/4; 
} 
.nestedfour{ 
  grid-column: 2/5; 
  grid-row: 2/4; 
}

When we run this code, we will notice, the nested grid takes a vertical stack arrangement even though their track is defined.

Subgrid- Nested Grid

Updating the .nestedfour class to inherit the column subgrid,

.nestedfour{ 
  display: grid; 
  grid-template-columns: subgrid; 
  grid-column: 2/5; 
  grid-row: 2/4; 
  background-color: rgb(212, 54, 81); 
  gap: 2px; 
}

we get this:

Subgrid - Proper Nested Grid

The nested grid automatically assumes the position of the parent column-template values. It takes up 100px, 200px, 1fr and 2fr as specified by the parent grid.

Subgrid on rows and columns

Using the same code as above, we will update it to include a subgrid for grid-template-rows.

.nestedfour{
  display: grid; 
  grid-template-columns: subgrid; 
  grid-template-rows: subgrid; 
  grid-column: 2/5; 
  grid-row: 2/4;
  background-color: rgb(212, 54, 81); 
  gap: 2px;
}

Subgrid- Paragraphs inside Subgrid

Notice that one of the nested cards, specifically card 7, is off the page. The reason: the parent grid allowed only three rows.

grid-template-rows: repeat(3,minmax(100px,auto));

Named Line Grid

CSS grid allows us to name our line grids and position items based on those names. It makes it a little easier than using line tracks.
Using a subgrid on a named line grid works perfectly as using it on line tracks. The line grid on the parent container is passed down to the Subgrid for an inheritance, and developers can place items on them if needed.
If there are multiple line names, we add the names after the subgrid values of grid-template-columns and grid-template-rows.

.container { 
  display: grid; 
  grid-template-columns: 1fr 1fr 1fr [cs] 1fr 1fr 1fr [cc] 1fr 1fr 1fr; 
  grid-template-rows: repeat(4, minmax(300px, auto)); 
  gap: 20px; 
} 
.box { 
  display: grid; 
  grid-template-columns: subgrid; 
  grid-template-rows: subgrid;
} 
.box1 { 
  grid-column: 1/ 3; 
  background-color: darkkhaki; 
}
.box2{ 
  grid-column: 3/5; 
  background-color: rgb(119, 119, 192); 
}
.box3{ 
  grid-column: 5/7; 
  background-color: green; 
}
<html> 
  <body> 
    <div class="container"> 
      <div class="box box1">This is box 1 
      </div> 
      <div class="box box2">This is box 2</div> 
      <div class="box box3">This is box 3 </div> 
    </div> 
  </body>
</html>

CSS Subgrid Highlights

  • Grid-gap inherits the parent gap, but you can override it by giving the grid gap a value.
  • Subgrids do not allow implicit dimensions. To override this, use grid-template-rows and grid-template-columns set to ‘auto’ to control the implicit track sizing.

Why do you need to use CSS Subgrid?

Subgrid is responsive to the browser, and the parent grid takes away the many hours of extra styling and positioning through extra code or JavaScript. It is straightforward to implement and easy to understand.

Subgrid Support

When this article was published, Subgrid is only supported on Firefox versions 71-79, 88, and 89-90. Chromium developers and others are working on having it available on different browsers.

Developers can write fallback alternatives for browsers that do not support subgrid.

@supports not (grid-template-columns: subgrid) { 
  //   ...write fallback code here ... 
}

Browsers that do not support Subgrid can use the code between curly braces as their alternative option.

Conclusion

Subgrid was initially supposed to be a part of the CSS Layout Module 1, but it failed to make it into the later released Layout Module 1 because of issues. Subgrid is the result of a lot of work, including use-cases and bug removal.
Since most browsers do not support Subgrid, it restricts many developers from using it. We look forward to having it handy because it would be a delight to use the many use-cases and designs developers can produce using subgrids.

Like this article? Please rate it!

Author

Ivaylo Ivanov

Ivaylo loves Frontend implementations. He is eager to construct interfaces that users love; pixel-perfect. In his day-to-day job, he caters to anything HTML, CSS, SCSS, or JavaScript-based on the frontend side. Complexity is not a problem, he masters VueStorefront implementations equally well to simple web apps or PWAs.
Experimentation with CSS and its' capabilities is Ivo's passion. Be it animated elements, or SVG animations - he loves it!