Container Queries Over Media Queries – Why?

Why Choose Container Queries Over Media Queries?

To create truly responsive designs, developers have long relied on media queries. But as layouts become more complex, media queries often fall short—focusing on the viewport instead of the actual components that need resizing. This is where container queries come in, offering a more flexible, component-based approach to responsiveness.

In this article, we’ll explore why container queries are a game-changer. We’ll start by understanding the limitations of media queries and why they struggle with modern design challenges. Then, we’ll break down how container queries work, how they differ, and when to use them for better scalability and adaptability.

Beyond the basics, we’ll look at real-world scenarios, including making reusable components that adjust dynamically without relying on the viewport size.

Without further ado, let’s dive in!

Understanding the Basics

Before we dive into practical implementation, let’s get the fundamentals straight. If you’ve ever wondered how websites adjust to different screen sizes or how some components magically resize within a layout, the answer lies in media queries and container queries. These two play a huge role in responsive design, but they work differently. Let’s break them down.

What are Media Queries?

Media queries are rules in CSS that allow you to apply styles based on the characteristics of the device or screen. In simpler terms, they check the size of the viewport (the visible area of a webpage) and adjust the layout accordingly. This is how web pages shift from a desktop view to a mobile-friendly design without breaking.

How do Media Queries Work?

Think of media queries as if they’re asking the browser:
"Hey, how wide is the screen?"

Based on the answer, different styles are applied. For example, if the screen width is less than 768px (a typical breakpoint for tablets), you might want to reduce font sizes or stack elements vertically.

Here’s a simple example:

@media (max-width: 768px) {

body {

background-color: lightgrey;

}

}

This rule tells the browser:
"If the screen width is 768px or smaller, change the background colour to light grey."

Common Media Query Breakpoints

While breakpoints can be customized, these are commonly used ones:

  • 320px – 480px: Small phones

  • 481px – 768px: Tablets

  • 769px – 1024px: Small laptops

  • 1025px – 1200px: Desktops

  • 1201px and above: Large screens

What are Container Queries?

Now, let’s talk about container queries—the game changer in modern responsive design. While media queries adjust styles based on the entire viewport, container queries look at the size of the parent container instead.

How do Container Queries Work?

Imagine you have a card component inside different sections of a website. With media queries, the card’s styling changes based on the screen width. But what if you want the card to adapt based on where it is placed rather than the screen size? That’s where container queries come in.

A container query asks:
"How big is the parent container?"

If the container shrinks, the child elements adjust accordingly. This makes components more flexible and reusable.

Here’s a simple example:

@container (min-width: 400px) {

.card {

font-size: 1.2rem;

}

}

This means:
"If the container holding the .card is at least 400px wide, increase the font size."

Key Difference: Media Queries vs. Container Queries

Feature

Media Queries

Container Queries

Based on

          Viewport (screen size) 

        Parent container size

Best for

        Layout adjustments across      devices

        Component-level responsiveness

Use case example

Changing the navbar layout on mobile

          Adjusting a card inside a sidebar

In short, media queries control the overall layout based on screen size, while container queries give components more independence by letting them adapt based on their parent container. If you’re building a fully responsive design, you’ll likely use both—media queries for overall structure and container queries for individual components.

The Problem with Media Queries

Media queries have been the go-to solution for responsive design, but let’s be honest—they have their limits. They adjust elements based on screen size, not the actual needs of individual components. This creates problems, especially in modern, complex UIs.

Global Breakpoints Are Limiting

Think of media queries like general announcements in a big lecture hall. They don’t consider individual students; they just assume everyone falls into broad categories. Similarly, media queries work on fixed screen widths (e.g., 768px, 1024px), but what if different components need different rules? You end up with a rigid system that doesn’t truly adapt to content.

Component Independence is Lacking

Let’s say you have a card component. On the sidebar, it should be small and compact. In a full-width layout, it should be bigger and more spacious. But with media queries, both cards will follow the same screen-wide breakpoints, whether they make sense for that particular layout or not. It’s like using the same shoe size for every occasion—sometimes it fits, sometimes it doesn’t.

Scalability Issues

As your project grows, you start stacking more and more media queries to handle different layouts. Before you know it, you’re dealing with a tangled mess of CSS rules that are difficult to manage. Small changes can break other UI parts, and debugging becomes stressful. If you’ve ever adjusted one media query only to find something else messed up, you're welcome to the struggle.

Why Container Queries Are Game-Changers

Unlike media queries, container queries allow components to respond to their own available space, not the whole viewport. That means truly flexible, reusable, and maintainable UI components.

Let’s break it down.

Component-Level Responsiveness

Think of a card component inside a grid layout. On a large screen, it might have lots of space, so you show a big image, a full description, and buttons. But when placed inside a smaller column, it should shrink automatically—maybe the image gets smaller, and the text wraps neatly.

With traditional media queries, you’d have to write styles based on screen sizes, hoping they fit every possible scenario. But with container queries, the component adapts to whatever space it has, no matter where it’s placed.

Better Reusability in Component-Based Development

If you’re working with React, Vue, or Angular, you already know how important component reusability is.

Container queries make it easier to create self-contained components that automatically adjust no matter where they’re used. This is a game-changer for design systems and UI libraries because it means less tweaking, fewer overrides, and more consistency across different projects.

For example, imagine designing a card component for a UI library. With container queries, that same card can be used in:

- A wide homepage grid with more content and bigger images

- A narrow sidebar with a compact layout

- A mobile-friendly view without needing additional styles

Instead of constantly writing “If the viewport is this, do that,” container queries allow components to style themselves naturally.

Improved Maintainability

Let’s be honest—global styles can be a nightmare. The more your CSS depends on screen sizes, the harder it is to manage. One small change can break layouts in unexpected ways.

Container queries reduce this headache by keeping styles local to each component. This means:

✅ Fewer global overrides

✅ Less CSS bloat

✅ Easier debugging and maintenance

Instead of chasing down why a button broke after a layout change, container queries let each component manage itself. This leads to cleaner code, better organization, and fewer unexpected bugs.

How to Use Container Queries in CSS

Here’s a simple example:

HTML

<article class='post-card'>

<div class='content'>

<img class='poster' src='https://creatures.dev/_astro/general-5.99bc4673_1aShEp.webp' />

<div class='post-data'>

<h4>Getting started with CSS Nesting</h4>

<p>CSS Nesting used to only be possible in CSS preprocessors like Sass and Less. But guess what, it’s now part of Native CSS! Let's see what's CSS Nesting and how we can get started using it.

</p>

<a href='https://creatures.dev/blog/getting-started-with-css-nesting'>Read on →</a>

</div>

</div>

</article>

Css

@layer styles {

:root {

--colors-bg-panel: #0f0f14;

--colors-bg-panel-hover: #1a1a24;

--colors-border: #1c1d29;

--colors-link: #ca5577;

--colors-text-primary: white;

--colors-text-secondary: #ffffffb3;

}

body {

background: #020208;

color: var(--colors-text-primary);

font-family: system-ui, sans-serif;

padding: 24px;

}

article.post-card {

background: var(--colors-bg-panel);

border: 2px solid var(--colors-border);

overflow: hidden;

transition: background 150ms ease-out;

padding: 12px;

border-radius: 12px;

position: relative;

/\ Declare the containment context on this element */*

container: post-card / inline-size;

/\ same as:*

container-name: post-card;

container-type: inline-size;

\/*

&:hover {

background: var(--colors-bg-panel-hover);

}

& div.content {

display: flex;

/\ Set the flex initially to column */*

flex-direction: column;

overflow: hidden;

& img.poster {

aspect-ratio: 16 / 9;

position: relative;

width: 100%;

border-radius: 12px;

margin-bottom: 12px;

overflow: hidden;

}

& div.post-data {

width: 100%;

padding: 12px;

display: flex;

flex-direction: column;

gap: 12px;

box-sizing: border-box;

& h4 {

font-size: 24px;

line-heigth: 32px;

margin: 0;

}

& p {

font-size: 14px;

line-height: 20px;

color: var(--colors-text-secondary);

overflow: hidden;

display: -webkit-box;

-webkit-box-orient: vertical;

-webkit-line-clamp: 3;

margin: 0;

}

& a {

color: var(--colors-link);

text-decoration: none;

font-weight: bold;

&::after {

content: " ";

position: absolute;

inset: 0;

}

}

}

}

}

}

/*

Define a style block for when the postcard

is at least 512px wide.

\/*

@container post-card (min-width: 512px) {

/*

The 'post-card' after @container sets the top-level

context to the article.postcard element, so all

selectors must target its descendants,

otherwise the styles will not be applied.

\/*

div.content {

/\ Change the card orientation to row */*

flex-direction: row;

align-items: center;

}

img.poster {

margin-bottom: 0px;

/\ Set the poster as the second child */*

order: 2;

}

/\ Increase visual values like gap, font-size*

and line-height \/*

div.post-data {

gap: 24px;

& h4 {

font-size: 2.75cqi;

line-height: 140%;

}

& p {

font-size: 1.5cqi;

line-height: 140%;

}

& a {

font-size: 1.5cqi;

line-height: 140%;

}

}

}

Adjust the browser to see the change.

Real-World Use Cases & Benefits

Container queries revolutionize responsive design by allowing components to adapt based on their parent container rather than the entire viewport. This makes UI components more modular, reusable, and flexible.

Here we have a featured post and an article card with a horizontal layout that spans across the whole width of the container, and then above that we have a grid of the same component but in a vertical layout, so we have the image first and then we have the metadata. This can be achieved easily with container queries

Let's explore some real-world applications:

Design Systems & Component Libraries: A New Era of Flexibility

In traditional CSS, reusable components depend on global viewport-based breakpoints, making them less adaptable. With container queries, components can dynamically adjust based on their container size, making them truly independent.

Example: A Card Component That Adapts to Its Parent Container

```css

/\ Enable container queries */*

.card {

container-type: inline-size; /\ Makes the card responsive to its container width */*

padding: 1rem;

border: 1px solid #ddd;

border-radius: 8px;

transition: all 0.3s ease;

}

/* When the container is at least 400px wide, adjust layout */

@container (min-width: 400px) {

.card {

display: flex;

align-items: center;

gap: 1rem;

}

.card img {

width: 150px;

height: auto;

}

}

```

How It Works;

- The .card component remains simple and responsive within any layout.

- If the parent container is less than 400px, the card stacks its content.

- If the container is at least 400px wide, the card switches to a horizontal layout.

Why is this a big deal?

Before container queries, you'd need extra utility classes, JavaScript, or rely on global breakpoints. Now, the component adapts naturally to different layouts.

Grid & Nested Layouts: Solving Problems Media Queries Struggle With

Media queries work well for full-page layouts but struggle with deeply nested components inside complex grids. Container queries allow each section of a grid to react independently.

Example: A Responsive Grid Layout Without Media Queries

```css

.grid-container {

display: grid;

grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

gap: 1rem;

}

/\ Make each grid item responsive within its container */*

.grid-item {

container-type: inline-size;

padding: 1rem;

background: lightblue;

border-radius: 8px;

text-align: center;

}

/\ Adjust styles if the grid item has enough space */*

@container (min-width: 300px) {

.grid-item {

font-size: 1.2rem;

font-weight: bold;

background: lightgreen;

}

}

```

How It Works

- Each .grid-item checks its own available space and changes its style accordingly.

- If a grid item gets at least 300px width, it increases its font size and changes colour.

- No need for complex media queries targeting .grid-container; each item responds individually.

Why is this a game-changer?

Normally, you'd need multiple media queries tied to screen sizes. Now, each grid item manages itself dynamically, making layouts more fluid.

Theming & Dynamic Interfaces: Adaptive UIs Without Relying on Viewport Changes

Container queries enable UI components to respond to their direct environment rather than the entire viewport.

This is especially useful in:

- Sidebars that expand/collapse

- Modals that resize based on content

- Widgets that adapt based on available space

Example: A Sidebar That Adapts Based on Its Width

```css

.sidebar {

container-type: inline-size;

width: 250px;

padding: 1rem;

background: #222;

color: white;

transition: width 0.3s ease;

}

/\ If the sidebar expands beyond 400px, change layout */*

@container (min-width: 400px) {

.sidebar {

display: flex;

flex-direction: column;

align-items: center;

}

.sidebar h2 {

font-size: 1.5rem;

}

.sidebar nav {

display: flex;

flex-direction: row;

}

}

```

How It Works

- The sidebar starts at 250px wide and behaves like a standard sidebar.

- When expanded beyond 400px, it changes its layout dynamically.

- This works without relying on global viewport-based media queries.

Why is this powerful?

Instead of adjusting UI based on screen width, the sidebar adapts based on its own size, making it perfect for collapsible panels, side widgets, and dashboard layouts.

Conclusion

Container queries mark a major shift in responsive design. Instead of a top-down approach where the viewport dictates everything, they enable a bottom-up model where components manage their own responsiveness.

This means:

✅ Cleaner CSS with fewer overrides

✅ More modular & reusable UI components

✅ Less dependency on JavaScript for adaptive layouts

If you’re not using container queries yet, now’s the time to start experimenting—they’ll change the way you build modern, scalable UIs.

0
Subscribe to my newsletter

Read articles from Onueze Mmasinachukwu directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Onueze Mmasinachukwu
Onueze Mmasinachukwu

I'm Onueze Mmasinachukwu, a Technical writer and a frontend developer. My articles are focused on web development. I love reading, writing and sharing my ideas with people.