Tailwind CSS Handbook v4.3

Container Queries

Style components based on the width of their container instead of the viewport — built into Tailwind v4 with no plugin required.

Core in v4 Container queries let a component respond to the space it has been given, not to the size of the browser window.

Overview#

Mark an element as a container, then style its descendants with @-prefixed variants:

HTML
<div class="@container">
  <div class="flex flex-col @md:flex-row">
    <!-- stacks until the container is 28rem wide -->
  </div>
</div>

Why they exist#

A breakpoint asks how wide is the window? A component usually needs to know how wide am I? Those differ the moment the same component appears in a sidebar and in a main column.

Loading preview…

With viewport breakpoints both cards would look the same, because the window is one width.

Container sizes#

VariantMin widthVariantMin width
@3xs16rem@2xl42rem
@2xs18rem@3xl48rem
@xs20rem@4xl56rem
@sm24rem@5xl64rem
@md28rem@6xl72rem
@lg32rem@7xl80rem
@xl36rem

Every size also has a @max-* counterpart: @max-md is @container (width < 28rem).

Common patterns#

Max-width container queries#

HTML
<div class="@container">
  <div class="flex flex-row @max-md:flex-col">…</div>
</div>

Ranges#

HTML
<div class="@container">
  <div class="flex flex-row @sm:@max-md:flex-col">…</div>
</div>

Named containers#

When containers nest, name them so a descendant can target the right one.

HTML
<div class="@container/sidebar">
  <div class="@container/card">
    <p class="@sm/card:text-lg @lg/sidebar:font-bold">…</p>
  </div>
</div>

Arbitrary sizes#

HTML
<div class="@container">
  <div class="flex flex-col @min-[475px]:flex-row">…</div>
</div>

Container query units#

cqw and cqh are percentages of the container, usable in arbitrary values:

HTML
<div class="@container">
  <div class="w-[50cqw]">Half the container's width</div>
</div>

Size containers#

v4.3 @container creates an inline-size container, which only tracks width. When you need block-size units such as cqb, use @container-size:

HTML
<div class="@container-size">
  <div class="h-[50cqb]">Half the container's height</div>
</div>

Customising container sizes#

Container sizes live in the --container-* namespace — the same namespace that powers max-w-*.

CSS
@import "tailwindcss";

@theme {
  --container-8xl: 96rem;
}

That gives you both @8xl:* and max-w-8xl.

Advanced example#

A product card that reflows through three layouts based on its own width:

Loading preview…

Comparison#

md: (breakpoint)@md: (container)
MeasuresViewport widthNearest @container ancestor
Needs a marked ancestorNoYes — @container
Survives being moved into a sidebarNoYes
Right forPage shell, global navCards, widgets, list items

Common mistakes#

  • Forgetting @container on the parent. Without it the variants match nothing — silently.
  • Querying the element itself. A container queries its descendants. Put @container on the wrapper, not on the element you are styling.
  • Using cqb without @container-size. Block-size units need a size container.
  • Replacing all breakpoints with container queries. Page-level structure still belongs to the viewport.

Tips#

  • Wrap the outermost element of a reusable component in @container as a matter of course. It costs nothing until you use a variant.
  • Container queries compose with everything else: dark:@lg:hover:bg-gray-800 is valid.
  • @container sets container-type: inline-size, which establishes containment — a rare source of surprise with absolutely positioned children.