---
title: "How CSS Container Queries Actually Work (And Where Elementor Still Needs Them)"
url: https://theplusaddons.com/blog/css-container-queries/
date: 2026-09-23
modified: 2026-09-23
lang: en
author: "Sagar Patel"
description: "[nexter-builder id=\"118291\"] Every responsive stylesheet carries the same quiet assumption: that the size of the browser window tells you something useful about the size of a component. For a page-level..."
image: https://theplusaddons.com/wp-content/uploads/2026/09/css-container-queries-featured-1024x538.jpg
word_count: 2188
---

# How CSS Container Queries Actually Work (And Where Elementor Still Needs Them)

## 

- Container queries let an element respond to the width of its own container, not the browser window, and the post says size container queries reach 93.96% global support while container query units reach 94.05%.
- The three core steps are to mark a parent with container-type or container, then query it with @container, and the post shows @container card (min-width: 420px) styling a .card inside a .card-slot wrapper.
- inline-size is the default choice because it queries width only, while size queries width and height and can collapse unless the container has an explicit height.
- cq units measure against the nearest container, and the post recommends cqi over cqw for vertical writing modes, with an example using clamp(1rem, 0.75rem + 2.5cqi, 1.75rem).
- Elementor's shipped CSS still uses viewport-based media queries only, with 434 @media rules and zero @container rules in Elementor 4.2.4 and 90 @media rules and zero @container rules in Elementor Pro 4.2.3.

Table Of Contents

Every responsive stylesheet carries the same quiet assumption: that the size of the browser window tells you something useful about the size of a component. For a page-level layout that holds up fine. For a card that appears in a wide hero on one page, a two-column grid on another, and a narrow sidebar on a third, it falls apart immediately. The viewport is 1440px in all three cases, so a media query gives all three the same treatment, and the sidebar version ends up with a four-column internal layout crammed into 280px.

Container queries fix that by letting an element respond to the width of its own container rather than the window. The feature is no longer new or experimental: according to the caniuse dataset, size container queries sit at 93.96% global support, and the container query units are at 94.05%. This guide covers what the three core properties do, how the cq units behave, a worked card example, the mistakes that cost people an afternoon, and an honest look at where Elementor stands right now.

## The Problem Container Queries Solve

Think about a product card with an image, a title, a short description and a button. In a wide slot you want the image on the left and the text on the right. In a narrow slot you want the image on top and the text underneath. With media queries the only question you can ask is how wide the window is, so you end up writing rules that are really guesses about where the card probably sits.

Those guesses get encoded as selectors like `.sidebar .card` or `.hero .card`, and each one is a separate branch you now have to maintain. Add a new page region and you write another branch. The card never becomes genuinely reusable, because its layout logic lives outside the card, scattered across whichever ancestors happen to exist. Container queries move that logic back inside the component, where it belongs.

## Container Queries vs Media Queries

These are not competing features. They answer different questions, and most real projects use both.

| Question | Media query | Container query |
| -------- | ----------- | --------------- |
| What is measured | The viewport, or the print page | The nearest declared ancestor container |
| Best used for | Page shell, global nav, spacing scale, print styles | Reusable components that appear in several slot widths |
| Reusability | Component behaviour depends on where it is placed | Component carries its own layout rules |
| Can query user preference | Yes, such as reduced motion or colour scheme | No, size and style queries only |
| Setup required | None | An ancestor must declare containment |

A practical division: keep the page skeleton and anything tied to user preference in media queries, and move component internals to container queries. Global spacing and colour tokens are a separate concern again, and they pair well with [CSS custom properties](https://theplusaddons.com/blog/css-custom-properties/), which you can redefine inside a container query to reflow a whole component from one declaration.

## The Three Lines That Make It Work

A container query has two halves. First you mark an element as a container. Then you write rules that ask about that container. Nothing happens until both exist, which is the single most common reason a first attempt does nothing at all.

`/* 1. Mark the parent as a query container */
.card-slot {
container-type: inline-size;
container-name: card;
}

/* Shorthand for both of the above */
.card-slot {
container: card / inline-size;
}

/* 2. Query it from inside */
@container card (min-width: 420px) {
.card {
display: grid;
grid-template-columns: 160px 1fr;
gap: 1.25rem;
}
}`

Read that second rule carefully, because the wording matters. It does not say "when the card is at least 420px wide". It says "when the nearest ancestor container named card is at least 420px wide, style the card this way". The element being measured and the element being styled are different elements, and that distinction causes most of the confusion covered further down.

## Choosing a container-type Value

There are three values, and picking the wrong one is the second most common failure. The short version is that `inline-size` is almost always what you want.

| Value | What you can query | Layout effect |
| ----- | ------------------ | ------------- |
| `inline-size` | Width only | Height stays automatic. Safe for almost everything. |
| `size` | Width and height | The element no longer sizes from its content, so it collapses unless you set a height. |
| `normal` | Style queries only | No size containment applied. |

The reason `size` behaves that way is not a bug. To answer a question about its own height, the browser has to fix that height before it looks at the children, otherwise the children would change the answer and the answer would change the children. Blocking that loop is the whole point of containment. Use `size` only when the container has an explicit height, and reach for `inline-size` the rest of the time.

## Container Query Units

Alongside the at-rule, container queries bring a set of units measured against the container instead of the viewport. They are the difference between a component that snaps at a few breakpoints and one that scales smoothly.

| Unit | Equals 1% of |
| ---- | ------------ |
| `cqw` | Container width |
| `cqh` | Container height |
| `cqi` | Container inline size, width in horizontal writing modes |
| `cqb` | Container block size, height in horizontal writing modes |
| `cqmin` / `cqmax` | The smaller / larger of cqi and cqb |

Prefer `cqi` over `cqw` if your site has any chance of being translated into a vertical writing mode, since it follows the writing direction rather than assuming horizontal. Pairing a cq unit with `clamp()` gives type that grows with its container but never runs past sensible limits.

`.card__title {
/* never below 1rem, never above 1.75rem, fluid between */
font-size: clamp(1rem, 0.75rem + 2.5cqi, 1.75rem);
}`

Note that cq units resolve against the nearest container, so an element with no container ancestor falls back to the small viewport size. If your fluid type suddenly looks enormous, check that the container declaration still exists above it.

## Naming Containers and Handling Nesting

An unnamed `@container` query resolves against the nearest ancestor container, whichever that happens to be. On a simple page that is convenient. Once containers nest, it becomes a guessing game, and names remove the guesswork.

`.layout { container: layout / inline-size; }
.sidebar { container: rail / inline-size; }

/* Explicitly asks the outer layout, not the rail */
@container layout (min-width: 60rem) {
.promo { padding-block: 4rem; }
}

/* Conditions combine the way media queries do */
@container rail (min-width: 240px) and (max-width: 420px) {
.promo__image { display: none; }
}`

Names are not unique identifiers. Several elements can share a container name, and each query resolves against the nearest ancestor carrying that name, which is what makes a named component pattern work across a page.

## A Card That Adapts to Its Slot

Here is the complete pattern. The same markup is dropped into a wide region and a narrow one, and the CSS never mentions either region.

`<div>
<article>
<img src="cover.jpg" alt="">
<div>
<h3>Reusable by default</h3>
<p>One component, three placements.</p>
</div>
</article>
</div>`

```
.slot { container: card / inline-size; }

/* Narrow slot is the default, no query needed */
.card { display: flex; flex-direction: column; gap: 1rem; }
.card__img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.card__title { font-size: clamp(1rem, 0.8rem + 1.8cqi, 1.5rem); }

/* Roomier slot: go horizontal */
@container card (min-width: 30rem) {
.card { flex-direction: row; align-items: center; }
.card__img { width: 40%; aspect-ratio: 1; }
}

/* Very wide slot: more breathing room */
@container card (min-width: 48rem) {
.card { gap: 2rem; padding: 2rem; }
.card__text { font-size: 1.125rem; }
}
```

Two details worth copying. The narrow layout is the default with no query wrapped around it, which means the card still renders sensibly if containment never applies. And the breakpoints are in `rem`, so they respond to the user's font size rather than locking to pixel values. The same mobile-first instinct that serves you well in [bento grid layouts](https://theplusaddons.com/blog/bento-grid-layout/) applies here.

## Where Elementor Sits Today

This is worth stating precisely rather than in slogans. Elementor's responsive controls are viewport based. Every device toggle in the editor maps to a breakpoint measured against the browser window, with the default desktop breakpoint at 1025px. That is a media query system, and it is a perfectly reasonable one for page layout.

To check how deep that goes, we scanned the stylesheets shipped with the current installs on this site. Across 60 core CSS files in Elementor 4.2.4 there are 434 `@media` rules and zero `@container` rules. Elementor Pro 4.2.3 shows 90 `@media` rules and, again, zero `@container` rules. So there is currently no container query layer in the product's own CSS, and no editor control that emits one.

That is a statement about the shipped stylesheets, not a limitation you are stuck with. Nothing stops you writing container queries yourself. Give the wrapper a CSS class in the Advanced tab, then add the rules through [custom CSS in Elementor](https://theplusaddons.com/blog/add-custom-css-in-elementor/).

`/* Container wrapper gets the class .cq-slot in the Advanced tab */
.cq-slot { container: slot / inline-size; }

@container slot (min-width: 32rem) {
.cq-slot .elementor-widget-image { float: inline-start; width: 45%; }
}`

One caution specific to builders. Declaring `container-type` on an element creates a containment context, and that has side effects on sticky positioning and on anything that relies on the element being a normal block. If a sticky header or an overlay stops behaving after you add containment, move the declaration to a dedicated wrapper rather than reusing a structural section. The trade-offs between wrapper types are the same ones covered in [flexbox and grid containers in Elementor](https://theplusaddons.com/blog/elementor-flexbox-vs-grid-container-differences/).

## Browser Support and Fallbacks

Support landed across the major engines within a few months of each other, and the feature has been widely available for well over two years.

| Browser | First version with full support |
| ------- | ------------------------------- |
| Chrome | 106 |
| Edge | 106 |
| Firefox | 110 |
| Safari | 16.0 |
| Safari on iOS | 16.0 |
| Samsung Internet | 20 |

Global support sits at 93.96% for size queries and 94.05% for the units, which puts container queries in the same practical bracket as `:has()` at 94.07%, a selector already used in production for things like the [CSS star rating pattern](https://theplusaddons.com/blog/css-star-rating/). If you need to be explicit about the fallback, feature detection is one rule.

`@supports (container-type: inline-size) {
.slot { container: card / inline-size; }
}`

In practice you rarely need it. Write the single-column layout as the default and treat every container query as an enhancement, and an unsupporting browser simply gets the stacked version, which was always the acceptable outcome.

## Five Mistakes That Break Container Queries

**Querying the element you styled.** An element cannot respond to its own size. Putting `container-type` and the queried styles on the same selector produces nothing. You always need a wrapper.

**Using `size` when you meant `inline-size`.** The container collapses to zero height because it can no longer take its height from its children, and the component appears to vanish.

**Forgetting that the wrapper must actually have a width.** A container that is itself an auto-width inline element gives you a meaningless number to query against.

**Assuming a named query falls back to an unnamed container.** If no ancestor carries that exact name, the query never matches. It fails silently rather than erroring, which makes a typo in a container name genuinely annoying to find.

**Breaking sticky positioning.** Containment changes how the element participates in layout. A previously sticky child inside a new container can stop sticking, which is usually solved by moving containment to a different wrapper. The same care applies to [theme toggles](https://theplusaddons.com/blog/wordpress-dark-mode/) and other patterns that depend on ancestor structure.

## Frequently Asked Questions

### Do container queries replace media queries?

No. Media queries remain the right tool for the page shell and for anything tied to the device or user preference, including reduced motion and colour scheme. Container queries handle component internals. Most sites use both.

### Are container queries slow?

Containment generally helps rendering performance, because it tells the browser that changes inside the container cannot affect layout outside it. The realistic caution is declaring containers on hundreds of elements when a handful of component wrappers would do.

### Can I query things other than size?

Style queries let you respond to a custom property value on the container, which is useful for theming variants. Support for style queries is narrower than for size queries, so treat them as a progressive enhancement rather than a foundation.

### Why is my container query being ignored?

Work through four checks in order: an ancestor declares `container-type`, the queried element is a descendant of it rather than the container itself, the container name in the rule matches the declaration exactly, and the container has a real measurable width.

### Does Elementor support container queries?

Elementor's responsive controls are viewport based, and a scan of the shipped stylesheets in Elementor 4.2.4 and Elementor Pro 4.2.3 found no `@container` rules. You can still write container queries yourself by adding a class to a wrapper and defining the rules in custom CSS.

### Should I use cqw or cqi?

Use `cqi` as the default. It tracks the inline axis, so it keeps working if the writing mode changes, and in a standard horizontal layout it resolves to exactly the same value as `cqw`.

### Suggested Reading

- [CSS Custom Properties Explained: How CSS Variables Actually Work](https://theplusaddons.com/blog/css-custom-properties/)

- [Elementor Flexbox vs Grid Container: The Differences](https://theplusaddons.com/blog/elementor-flexbox-vs-grid-container-differences/)

- [Masonry Grid: Native CSS Grid Lanes vs Elementor](https://theplusaddons.com/blog/masonry-grid-css-vs-elementor/)

- [Bento Grid Layouts: CSS Grid vs Elementor](https://theplusaddons.com/blog/bento-grid-layout/)