Solomon Esenyi Python/Golang developer and Technical Writer with a passion for open-source, cryptography, and serverless technologies.

Using CSS subgrids with container queries

5 min read 1641

If you work with CSS often, you may have experienced layouts placed side-by-side that break or become misaligned when one side’s size changes. Almost every web designer has faced this, and it can be frustrating to resolve. Luckily, CSS has features allowing you to create web layouts that maintain alignment when their content changes; these are called the subgrid and container queries.

CSS subgrid and container queries are two features that can vastly improve web layout design and responsive web development. This article will dive deeply into CSS subgrids by providing a tutorial on seamlessly using them with container queries.

Contents

What are CSS subgrids?

CSS subgrids are a relatively new feature in the CSS ecosystem, proving to be a significant addition to the level two CSS grid web design and layout specifications.

The elements (child components) you construct and adjust inside a traditional grid container do not directly inherit rows and columns from their parent component. This causes difficulty in consistently aligning them with the parent grid, as each element tends to act independently.

You then have to manage two separate grids, which can get redundant. You can quickly solve this problem by adding subgrid as a value for the grid-template-rows and grid-template-columns properties, because grid child components can now perfectly sync with their parent component.

CSS subgrids allow the child components to inherit their parent row and column settings without maintaining their grid settings.

Consider the three cards in a nested grid system below:

Cards in a nested grid system

Look what happens when you increase the card’s content at the center:

Nested grid cards increased center content



You can immediately see that the title and footer positions get compromised as the content increases.

There are several ways of dealing with this problem. Still, they all end up with you manually managing individual grids in nested grid systems, which can be problematic when working on a larger codebase.

Subgrids now provide an alternative fix that allows rows and columns to maintain their initial position in the grid system despite changing their content.

From my example above, adding subgrid as the value for my card’s grid-template-rows will produce a different output:

.card {
  grid-template-rows: subgrid;
}

Here’s the result:

subgrid cards

Despite the second card’s content increase, the title and footer elements are still perfectly positioned and in sync with the parent grid.


More great articles from LogRocket:


Subgrid is a significant addition to CSS grid layout specifications because of the ability of child components to inherit the properties of their parent and grandparent components. It comes in handy when building nested grid systems, perfectly aligned form layouts, and other editorial web alignments.

Currently, only Firefox browser supports CSS subgrid, but other popular browsers are not far behind. You can reference this guide to look deeper into CSS subgrids and their functions.

What are container queries?

Since the introduction of media queries to browsers, responsive web design has taken a giant step into the future, as you can now design specific layouts for browser viewports.

This is great, but media queries have also exposed a redundancy issue when creating more complex web structures. For instance, components wrapped in a containing section that need to adjust their primary layout properties (like width or height) to line up with a change in the web page’s viewport can affect and break the design.

To solve this problem, keep the component’s media queries in sync with the containing section to ensure that your component looks good on all viewport sizes. You can easily solve this with container queries because instead of viewport sizes, you now design elements based on their actual properties. Container queries allow any component to respond per a specified container.

In a grid system, for instance, child components can align with their container and determine their behavior and responsiveness. You can modify their styles depending on their position in the container (not the viewport). While you can still structure web pages with a responsive grid layout, using container queries is a more straightforward approach to responsive web design.

How do container queries work?

The first thing to understand about CSS container queries is that while “containers” are the elements being queried, the rules within container queries only affect the container descendants. For instance, if you query a main, section, or perhaps a div as your target container, container queries will allow you to define rules for how elements within them change as the container size changes.

You can create a container query with @container. It looks for the closest containment context:

.card {
  display: flex;
  flex-direction: column;
}

.container {
  background: #fff;
  container-type: layout inline-size
  container-name: something;
}

@container something (min-width: 450px) {
  .card {
    display: flex;
    flex-direction: row
  }
}

The code above is an illustration of working with container queries. It simply instructs the browser to change the value of the card’s flex-direction column to row if the container’s width is at least 450px.

Container queries were specified to be included in CSS containment. Three properties accompany them:

1. container-type

This property assigns a query container to an element so that its child components can query several aspects of its layout features.

  • size creates a query container for block and inline axis dimensional queries. Layout, style, and size containment are applied to the element
  • inline-size creates a query container for dimensional queries on the container’s inline axis. The element’s layout, style, and inline-size containment are applied
  • block-size creates a query container for dimensional queries on the container’s block axis. Layout, style, and block-size containment are applied to the element
  • style is for style queries, and creates a query container
  • state creates a query container for state queries

2. container-name

An optional property that further specifies the container’s name. This attribute acts as an escape hatch when we don’t want to target the nearest parent container.

Consider the code below:

.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

The CSS above generates a container with a specified name (sidebar) that only contains content on the inline axis, meaning that the content can grow as much as it needs to on the block axis. You can then query that specific container with its container-name like so:

@container sidebar (min-width: 450px){
  .card {
    display: flex;
    flex-direction: row
  }
}

3. container

This property is often used as a shorthand property you can use to set both container-type and container-name in one statement.

Use cases for container queries

Container queries are appropriate for highly reusable components with a layout dependent on the available container space. They can be used in various situations or added to multiple containers on the page.

Other container query use cases include:

  • Adaptable layouts
  • Cards, form elements, banners, and other modular components
  • CSS resize experiments
  • Mobile and desktop pagination with distinct functionalities

Most browsers still do not support container queries, but you can readily test their features on Google Chrome Canary. Head to chrome://flags and enable CSS Container Queries:

Enabling css container queries

You can also experiment with container queries on Mozilla Firefox by heading to about:config and enabling layout.css.container-queries:

enabling container queries firefox

Container queries are currently in their first public working draft, but it is a feature that has proven helpful and is likely to be incorporated in all browser versions.

Using CSS subgrids with container queries

CSS subgrids and container queries are two fascinating CSS features that I think will change your approach to webpage layout design and responsive styling, but how can we combine them?

Say we have a section containing three articles in the following format:

<section class="container">
  <article class="article1">...</article>
  <article class="article2">...</article>
  <article class="article3">...</article>
</section>

Now let’s place these articles in a nested grid system where subgrids and container queries can play their roles:

/* this creates a container with containment on the inline axis only and gives it an optional name "main" */
html, section {
  container-type: inline-size;
  container-name: main;
}

/* targeting the section's minimum width at "60ch" */
@container main (min-width: 60ch) {
  section {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

/* targeting the section's minimum width at "100ch" */
@container main (min-width: 100ch) {
  article {
    padding: 1rem;
    font-size: 1rem;
    border: 1px solid #000;
    margin: 10px 20px;
    display: grid;
    grid-template-rows: auto 1fr auto;
  }

  /* enabling a more responsive grid layout so elements don't break */
  .article1, .article2 {
    grid-template-columns: subgrid;
  }

  .article3 {
    display: grid;
    grid-column: span 2;
  }
}

/* targeting the section's containment context at a maximum width of "100ch" */
@container main (max-width: 100ch) {
  main {
    display: flex;
    flex-direction: column;
  }
}

From the above CSS code, we made the first two columns take as much space in a two-column grid system as the third one, which is just below. We then created a subgrid inside the article to ensure the elements inside are in sync and can’t break, even when the article’s content is increased.

example card grid system

To make this system more responsive, we had to target the section and set some container query rules that apply to the articles as their descendants. You may notice that we queried the inline-size property of the section because we want the article (child) components to grow or shrink inline with the section’s (container) width.

In this case, we made the articles flex in the column direction when the section’s width is at a maximum of 80ch. This enables our articles to respond not to the viewport size but their container’s width.

Here’s the result:

container queries subgrids working together

Conclusion

This article covered CSS subgrids and container queries, their workings, and use cases. We were also able to experiment with both concepts and combine them to bring about a responsive layout. Container queries and CSS subgrids are currently in their first public working draft, but they are features that have proven helpful and are likely to be incorporated in most new browser versions.

I hope this article was valuable to you. Happy coding!

Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web and mobile apps — .

Solomon Esenyi Python/Golang developer and Technical Writer with a passion for open-source, cryptography, and serverless technologies.

Leave a Reply