Imagine you’re building a responsive layout for a website showcasing pets. Your grid works perfectly at different screen sizes, but then, you receive requirements to embed a pet carousel into a sidebar. The grid breaks because resizing the carousel's parent container isn’t accounted for in your design. Sound familiar?

This is where Container Queries shine- a game-changer for responsive design. They’ve been available for a few years now but still seem to be largely under-utilised. While media queries let you design based on the viewport size, container queries let you design based on the size of individual containers. In this article, we’ll dive deep into container queries, why they matter, and how to use them effectively.

What Are Container Queries?

#

Essentially; Container queries are CSS rules that allow you to style elements based on the size of their parent container rather than the viewport.

Traditionally, the way we handled styling of elements in different screen sizes was by using Media Queries.


_10
/* min-width is referencing the size of the screen */
_10
@media (min-width: 40rem) {
_10
.mobile {
_10
display: none;
_10
}
_10
}

Media queries are great; they’re also still really useful. But their limitation is that they are concerned with high-level, global properties, things like the viewport dimensions of the screen. Container Queries give us finer grain control as they’re only concerned with local properties such as the computed width or height of parent elements.


_10
/* min-width is referencing the size of the parent element */
_10
@container (min-width: 40rem) {
_10
.mobile {
_10
font-size: 1.5rem;
_10
}
_10
}

The Essence Of Container Queries

#

Simple enough right? Let’s dive into a example of how we can use container queries in a basic React project.

Playground
import React from "react";
import "./styles.css";
import Container from "./Container";

export default function App() {
  return (
    <Container>
      <div className="card">
        <h2>Responsive Card</h2>
        <p>This card adjusts based on its container size.</p>
      </div>
    </Container>
  );
}

In this example, we create a Container component that renders child components. We then create a CSS class .container which has a max-width of 450px with container-type CSS property to enable container queries and then define rules for .card elements based on the container size in styles.css

Finally in our app App we add the card element inside the container and the card’s styles dynamically adjust as the container resizes. By resizing the editor pane in the above example you can see container queries in action.

Stay ahead of the pack 🐶

Join the newsletter to get the latest articles and expert advice directly to your inbox.
Totally free, no spam and you can unsubscribe anytime you want!

  • Expert Tips
  • No Spam
  • Latest Updates

I'll never share any of your information with a third party. That's a promise.

Containment Context

#

To register a containment context, you use the container-type property. This property not only makes an element a container but also decides which of its properties can be queried.

Size containment

We can measure and track an element’s dimensions like width, height, aspect ratio using container size queries, but only if we register the element as a container. This tracking takes some processing power. A few elements are fine, but constantly tracking every element on the page; especially during resizing or scrolling would slow things down. That’s why elements don’t have size containment by default. To enable it, we use the container-type property in CSS. The three possible values are normal, size, and inline-size.


_10
@container (min-width: 300px) {
_10
.card { font-size: 1rem; }
_10
}

Style containment

This lets us check and use certain style properties of an element through container style queries. For now, we can only query custom properties like --theme: dark, but soon we’ll be able to check for things like an element’s background-color or display values. Unlike size containment, style containment doesn’t require extra processing, so all elements have it by default, meaning you don’t need to register anything for style containment.


_10
@container style(--theme: dark) {
_10
.card { color: #fff; }
_10
}

You can also target a query to target both!


_10
@container (width > 300px) and style(--theme: dark) {
_10
.card {
_10
font-size: 1rem;
_10
color: #fff;
_10
}
_10
}

Understanding Container Query Properties

#

We initialise container queries via several CSS properties:

container-name: Registers an element with a unique name that can be queried for styling based on its size.


_14
.parent {
_14
container-name: sidebar;
_14
}
_14
_14
.child {
_14
display: flex;
_14
flex-direction: column;
_14
}
_14
_14
@container sidebar (width > 10rem) {
_14
.child {
_14
flex-direction: row;
_14
}
_14
}

container-type: Defines the dimension that the container can be queried on. It can be one of three options:

container-type: size The size of the container is computed in isolation, ignoring the sizes of its child elements. This ensures the container's dimensions are predictable and independent of its content. It’s Perfect for components that need to adapt dynamically to both their width and height, such as flexible cards or grid items.

container-type: inline-size The inline size of the container is computed independently, ignoring the size of its child elements. Ideal for layouts that primarily depend on width changes, such as sidebar navigation or responsive column elements.

container-type: normal This is the default value. The element does not become a query container for container size queries (size or inline-size). However, it remains a query container for container style queries, allowing styles to be scoped and isolated. This is Suitable when you only need style-based containment but don’t need to query the element’s dimensions.


_14
.parent {
_14
container-type: inline-size;
_14
}
_14
_14
.child {
_14
display: flex;
_14
flex-direction: column;
_14
}
_14
_14
@container (width > 10rem) {
_14
.child {
_14
flex-direction: row;
_14
}
_14
}

container: Is a shorthand property that combines both container-name and container-type into a single declaration.


_14
.parent {
_14
container: sidebar / inline-size;
_14
}
_14
_14
.child {
_14
display: flex;
_14
flex-direction: column;
_14
}
_14
_14
@container sidebar (width > 10rem) {
_14
.child {
_14
flex-direction: row;
_14
}
_14
}

In the next example, we register a new container named card-grid that can be queried by its inline-size.

Playground
import React from "react";
import "./styles.css";

export default function App() {
  return (
    <div className="card-grid">
      <div className="card">Card 1</div>
      <div className="card">Card 2</div>
      <div className="card">Card 3</div>
    </div>
  );
}

Using Container Query Length Units

#

With the introduction of container queries comes the addition of several new units specifically for container queries. These units allows us to make precise adjustments to element styles based on their parent container's size.

cqw (Container Query Width): Represents 1% of the query container's width. This is useful when you want an element to scale proportionally to the container’s width, such as setting its width or horizontal padding: width: 50cqw; makes the element’s width 50% of the container’s width.

cqh (Container Query Height): Represents 1% of the query container's height. Use this for height-based styles like vertical padding or overall element height: height: 20cqh; makes the element’s height 20% of the container’s height.

cqi (Container Query Inline Size): Represents 1% of the container's inline size, which corresponds to width in horizontal writing modes (like English) and height in vertical writing modes (like Japanese): border-radius: 10cqi; ensures the border radius adapts to the inline size, making designs more responsive to different writing directions.

cqb (Container Query Block Size): Represents 1% of the container’s block size, which corresponds to height in horizontal writing modes and width in vertical writing modes: padding: 2cqb; adjusts the padding based on the container’s block size.

cqmin (Container Query Minimum Size): Represents the smaller value of either cqi or cqb. This is ideal for scaling styles that should adapt to the more constrained dimension of the container: font-size: 5cqmin; keeps text legible by scaling it based on the container’s smallest dimension.

cqmax (Container Query Maximum Size): Represents the larger value of either cqi or cqb. Use this for styles that should expand proportionally to the larger dimension of the container: font-size: 6cqmax; scales text dynamically with the container’s largest dimension.

This approach ensures a more modular especially towards dynamic layouts. We can see how powerful these units illustrated in this example.

Playground
import React from "react";
import "./styles.css";


export default function App() {
return (
<div className="container">
<div className="box">Resize Me</div>
</div>
);
}

Conclusion

#

Container queries bring a new level of adaptability to component-based design.

It may sometimes feel like they are a solution looking for a problem. However; it’s important to understand that container queries and media queries exist to solve very specific use cases.

It’s with the new addition of container queries we are offered finer grain control over the behaviour of how the user interface responds. They allow us to design our code in a more modular way by only having to think about how elements behave with respect to their parent elements rather than the entire viewport.

With that being said- don’t be afraid to play around with the examples above to get to grips with the awesome power of container queries and have a think about what cases you can use them in your latest apps.

Happy coding!

DANNY

Reinforce Your Learning

One of the best ways to reinforce what your learning is to test yourself to solidify the knowlege in your memory.
Complete this 9 question quiz to see how much you remember.

1) What does the `container-type` property do in CSS?

Thanks alot for your feedback!

The insights you share really help me with improving the quality of the content here.

If there's anything you would like to add, please send a message to:

[email protected]

Was this article this helpful?

D is for danny

About the author

Danny Engineering

A software engineer with a strong belief in human-centric design and driven by a deep empathy for users. Combining the latest technology with human values to build a better, more connected world.

Gobacktothetop

Made with 🥰 in 🏴󠁧󠁢󠁥󠁮󠁧󠁿

©2025 All rights reserved.