Making Consistent Web Layouts With Subgrid

Prerequisites

  • You should have a basic understanding of HTML and CSS.

  • A solid grasp of CSS Grid is necessary.

  • Make sure you have an updated browser, preferably Chrome.

Introduction

While CSS subgrid has been around for quite some time, it only recently became stable in the past few months. In case you're unfamiliar with subgrid, it's essentially a version of the CSS grid layout designed to simplify handling the quirky behaviors often encountered with grids.

Have you ever faced issues with elements not aligning as expected or elements overlapping each other at different screen sizes? CSS subgrid offers a more effective and straightforward solution to address these kinds of problems.

This article will guide you through the features that CSS subgrid brings to the design table and demonstrate how it can solve design problems that might be challenging to tackle directly with a standard grid.

Goals

By the end of this article, you will have a clear understanding of:

  • The underlying issue with the standard grid.

  • The concept of subgrid and its practical application.

  • The drawbacks and limitations associated with using subgrid.

The Issue With Grid

The problem arises when we set the display of a container to grid. In such cases, only the direct children of the container can access the lines, rows, columns, and areas defined on the parent container.

This limitation complicates the alignment of nested layouts within the children of that container with their ancestors. The well-named grid information created for the parent container becomes inaccessible to the nested layouts inside the children.

What Subgrid Has to Offer

Unlike the standard grid, where using display: grid creates an independent layout for direct children, subgrid allows you to establish a new grid layout that incorporates the features of a parent layout. This means that the nested layouts within the direct children of the parent grid element can access the styles of the parent grid element.

The key advantage is achieving more consistent grid systems and layouts.

In simpler terms, without subgrid, it's not possible for indirect children to access the styling of a parent grid. This limitation hinders achieving consistent styling for both direct and indirect children in a grid layout.

Subgrid becomes especially valuable in scenarios where varying line lengths, influenced by user interactions with your website, might disrupt your carefully planned alignment. With subgrid, the indirect children of your main grid container (if you're using grid) can now be aligned seamlessly, offering a solution to such challenges.

How is Subgrid Used?

To grasp how subgrid is used, it's essential to understand the syntax provided below:

The snippets in this section serve as an explanation of how subgrid functions. A comprehensive demonstration with a visual representation of subgrid will be presented in the following paragraphs for a more practical understanding. Please note that the snippets here are for explanatory purposes only.

.parent {
  display: grid;
  grid-template-columns: 1fr [main-start] 1fr 1fr 1fr [main-end] 1fr;
}

.child {
  grid-area: main;
  display: grid;
  grid-template-columns: subgrid;
}
  • The .parent class serves as a grid container.

  • It features a defined grid layout with columns set through the grid-template-columns property.

  • The columns are specified using fractional units (1fr) and are named lines [main-start] and [main-end].

  • This configuration establishes a grid with seven columns, wherein the middle three columns are named main-start and main-end, each occupying one fractional unit of space.

  • The .child class represents a child grid directly nested within the parent grid.

  • Using grid-template-columns: subgrid; signifies that the columns of the descendants within this child grid should align with the columns of its parent grid. Essentially, it inherits the column definition from the parent.

Please note that subgrid is a value of the grid property. Despite its name, it may sound like a standalone display property, but this is not the case.

Subgrid is utilized to define grid rows and columns. Specifically, it can be applied to grid-template-columns or grid-template-rows, and in no other scenarios. The subgrid keyword is exclusively used in these instances.

In essence, it involves delegating the responsibility of defining the grid columns or rows of the indirect element to its parent. It instructs the browser to derive the template for the indirect child from its parent, resembling a design inheritance pattern.

You can have a grid with automatically sized rows, while its child grid utilizes subgrid for columns or rows, potentially incorporating auto-sized columns. This flexibility allows for a versatile and adaptive layout structure, tailoring the sizing and positioning behavior according to the specific requirements of rows and columns in various parts of the layout.

.parent {
  display: grid;
  grid-template-rows: auto 1fr; /* First row is auto-sized, second row takes remaining space */
  grid-template-columns: 1fr 1fr; /* Two columns taking equal space */
  gap: 10px; /* Gap between grid items */
}

/* Child grid using subgrid for rows and auto-sized columns */
.child {
  display: grid;
  grid-template-rows: subgrid;
  grid-template-columns: auto auto; /* Auto-sized columns */
  gap: 5px; /* Gap between grid items in the child grid */
}
  • In the provided code snippet, the .child element demonstrates the ability to combine auto placement for its columns and utilize subgrid for its rows.

Additionally, it's essential to highlight that while the line numbers of the parent grid are not inherited, the grid names are passed down. These names can be reassigned on subgrids, providing the flexibility to rename the inherited subgrid columns and rows on the fly.

Solving a Design Problem With Subgrid

In this section, we will be crafting a demo featuring a board of cards. Each card will include a text paragraph accompanied by a responsive picture to effectively showcase grid layouts. Subsequently, we will address a recurring issue with grids, proposing a solution by appropriately implementing subgrid.

  1. Create two files for the demo.
/subgrid.html
/subgrid.css
  1. In subgrid.html, we will have our main structure and some images from unsplash.
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Subgrid Demo</title>
    <link rel="stylesheet" href="subgrid.css" />
  </head>
  <body>
    <div class="card-grid">
      <div class="card">
        <h2>Lorem ipsum</h2>
        <p>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Assumenda
          recusandae maxime distinctio quos ullam incidunt.
        </p>
        <img src="//unsplash.it/501" alt="" />
      </div>
      <div class="card">
        <h2>Omnis, veritatis odio.</h2>
        <p>
          Enim molestiae recusandae ut dolor sit amet consectetur adipisicing.
          odit possimus eius inventore. Quasi illo unde neque? Itaque, deleniti
          adipisci?
        </p>
        <img src="//unsplash.it/502" alt="" />
      </div>
      <div class="card">
        <h2>Exercitationem, libero quam!</h2>
        <p>
          Error maiores culpa eaque. Quam quisquam quae nostrum ipsa dolorum
          atque aperiam fugit soluta error!
        </p>
        <img src="//unsplash.it/503" alt="" />
      </div>
      <div class="card">
        <h2>Quibusdam, recusandae odio.</h2>
        <p>
          Corporis laboriosam, neque est commodi architecto voluptatem, ipsam
          corrupti ullam similique eligendi hic qui natus?
        </p>
        <img src="//unsplash.it/504" alt="" />
      </div>
      <div class="card">
        <h2>Modi, exer citat ionem dicta.</h2>
        <p>
          Laboriosam, aliquam tempore minus dolorem ullam et veniam asperiores,
          eveniet vitae odit itaque eligendi ducimus?
        </p>
        <img src="//unsplash.it/505" alt="" />
      </div>
      <div class="card">
        <h2>Dolore.</h2>
        <p>
          Reprehenderit, labore. Lorem ipsum dolor sit amet, consectetur
          adipisicing elit. Sunt, aut. harum vitae voluptate alias saepe debitis
          quo perspiciatis, delectus fugiat modi eveniet.
        </p>
        <img src="//unsplash.it/506" alt="" />
      </div>
    </div>
  </body>
</html>
  • The HTML file is linked to our CSS, and the primary structure is a main grid, <div class="card-grid">, containing child elements that are grids themselves, <div class="card">.

  • Here's how the HTML structure should look like:

  1. Using subgrid.css, style the HTML markup.
body {
  font-size: 1.125rem;
  line-height: 1.5;
}

.card-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: 1fr 1fr;

  /*   other styling */
  width: min(90%, 60rem);
  margin-inline: auto;
}

.card {
  display: grid;
  grid-template-columns: minmax(6ch, 20ch) 1fr;
  grid-template-rows: min-content 1fr;
  gap: 1em;
  border: 3px solid black;
}

.card h2 {
  grid-column: 2;
  padding-top: 1rem;
  padding-right: 1em;
  font-size: 1.75rem;
  line-height: 1;
}

.card p {
  grid-column: 2;
  padding-bottom: 1rem;
  padding-right: 1em;
}

.card img {
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

img {
  max-width: 100%;
}

h2,
h3,
p {
  margin: 0;
}

h1 {
  margin: 2em;
  text-align: center;
}
  • Pay attention to the main classes, .card-grid and .card, as they house crucial grid declarations. .card-grid is responsible for styling the entire layout, while .card manages the positioning of text and images in a grid format.

  • Observe the proper alignment of text and images when the browser view-port is maximized:

The page appears well-designed. However, note in the image below that as we resize the viewport, there is a point at the mid-size of the viewport where the images and texts of different cards are no longer aligned as they were in the largest size of the viewport:

The reason for this misalignment is not due to any issue with our CSS but is inherent to the way the grid operates.

In our demo, we have a primary class for the layout, .card-grid, and a class for styling the direct children of the main class element, .card.

The challenge arises because the direct child elements of the .card-grid class align perfectly with the grid declaration of the main element's class. However, the elements styled with .card take their grid declarations from .card-grid. Due to the nature of grid operations, the indirect children – the text and images inside the .card div's – cannot access this grid declaration.

Additionally, content plays a role in this misalignment. Since the text and images cannot access the grid declaration of their ancestor class, .card-grid, their layout is determined by the space they can occupy.

Take note of two of the card div's and observe how text with lengthier headings occupies more space than their images, while texts with smaller headings occupy less space:

To address this issue effortlessly, we can utilize subgrid. Here's what you need to do:

  1. In subgrid.css, make the following changes to .card-grid and .card class selectors:
.card-grid {
  display: grid;
  gap: 2rem;
  grid-template-columns: minmax(6ch, 20ch) 1fr minmax(6ch, 20ch) 1fr;

  /*   other styling */
  width: min(90%, 60rem);
  margin-inline: auto;
}

.card {
  grid-column: span 2;
  display: grid;
  grid-template-columns: subgrid;
  grid-template-rows: min-content 1fr;
  gap: 1em;
  border: 3px solid black;
}
  • In the CSS code above, significant changes were made to the .card-grid and .card classes.

  • The grid-template-columns for the grid parent is modified to minmax(6ch, 20ch) 1fr minmax(6ch, 20ch) 1fr;. This adjustment is made in anticipation of using subgrid to make the contents of the .card class inherit four columns from .card-grid.

  • Within the .card class, the property grid-column: span 2; is applied, signifying that each instance of .card should span two columns in the parent grid, .card-grid.

  • The subgrid value in the .card class means that the child grid inherits the grid definition from its parent, which is .card-grid. Consequently, any content inside it should inherit the grid definition from .card-grid.

  • Note that regardless of how the page layout is resized, all the content inside .card elements is consistently aligned, thanks to the implementation of subgrid:

Inspecting with Devtools

To ensure that our subgrid is functioning independently of the main grid, let's observe this in DevTools. I'm using Chrome, but you can use any browser that supports subgrid.

  1. Open Chrome Developer Tools on the layout demo by either right-clicking and choosing "Inspect" or pressing Option + ⌘ + J (on macOS) or Shift + CTRL + J (on Windows/Linux).

  1. Click on the "grid" badge on the element <div class="card-grid">. Take note in the image below that this action sets the grid overlay of red rows and columns for the grid and its direct children.

  1. Now, on the direct children of the main grid element, click on the "subgrid" badge. Take a close look at the image below; this applies a gold overlay to the content in the <div class="card"> element.

This subgrid overlay perfectly aligns with the grid overlay, confirming that subgrid indeed ensures consistent alignment of grid layouts, from the parent grid element to the direct children and down to descendants.

Subgrid Tradeoffs

Subgrid comes with a few important tradeoffs that we'll explore in this section.

A subgrid is closely tied to a direct parent grid, as its tracks depend on those of the parent or a subset of the parent's tracks.

This means careful consideration is needed for the number of items that fit into the parent grid. If there are too many items, using subgrid becomes challenging, and you may need to define new rows and columns instead.

A parent grid can have both explicit and implicit grid tracks. Implicit tracks are automatically created to accommodate items that exceed the explicitly defined tracks.

In contrast, a subgrid is less flexible because it relies on the explicit grid definition of its parent container and does not create implicit tracks.

However, if a parent grid track is sized using auto, its size is determined by the content it contains. In the case of a subgrid, the size of its tracks within the parent can impact the size of the parent's tracks if the parent's track is set to auto.

In summary, while subgrid enables the inheritance of grid layouts, it is not as accommodating as the main grid. Despite its limitations, subgrid proves beneficial for achieving more complex layouts.

Browser Support

Despite being on the waitlist for widespread stable support for a considerable duration, subgrid is now fully supported on all major browsers.

Conclusion

In conclusion, CSS subgrid emerges as a valuable addition to the toolkit of web developers seeking consistent and responsive web layouts.

This article delved into the essence of subgrid, exploring its role in overcoming challenges inherent in traditional grid layouts.

By providing a seamless way to inherit grid definitions from parent containers, subgrid enables developers to create more cohesive and adaptable designs.

The journey through this article highlighted the fundamental issues with grid layouts and introduced subgrid as a solution to bridge the gap between parent and child grid elements.

Demonstrating the syntax and usage of subgrid, we illustrated how it empowers developers to create versatile and consistent grid systems.

However, it's important to acknowledge the tradeoffs associated with subgrid. While it enhances consistency and alignment, subgrid is tightly coupled with its direct parent grid, making it crucial to manage the number of items within the grid to maintain its effectiveness.

Additionally, subgrid lacks the flexibility of implicit tracks, relying solely on the explicit grid definition of its parent container.

The practical application of subgrid was showcased through a demonstration, highlighting a common design problem and showcasing how subgrid resolves alignment issues. By incorporating subgrid into the CSS layout, we achieved a responsive and perfectly aligned grid structure.

For further exploration and learning, check out additional resources to deepen your understanding of subgrid and its capabilities. As the pursuit of perfect web layouts continue, subgrid stands out as a handy tool for achieving harmony in grid-based layouts. Happy coding !

Resources