Container & Container Queries

Style by Parent Size, Not Just Viewport

Container & Container Queries

Use the container utility for centered max-widths, and v4's built-in container queries to style based on a parent's width.

4 min read Level 3/5 #tailwind#layout#container-queries
What you'll learn
  • Use the container utility with centering
  • Mark a container and use its size variants
  • Know when container queries beat breakpoints

Breakpoints answer “how big is the screen?” Container queries answer “how big is this element’s parent?” — and in v4 they need no plugin.

The container Utility

container sets a max-width that steps up at each breakpoint. Pair it with centering and padding for the standard page wrapper:

<div class="container mx-auto px-4">
  <!-- page content, centered with sane gutters -->
</div>

This is layout based on the viewport. Useful, but it knows nothing about where a component actually sits.

Container Queries

Mark an ancestor as a query container with @container, then style children with @-prefixed variants based on that container’s width:

<div class="@container">
  <article class="flex flex-col @md:flex-row gap-4">
    <img class="@md:w-1/3" src="/cover.jpg" alt="" />
    <div class="@md:w-2/3">
      <h3 class="text-base @lg:text-xl">Card title</h3>
    </div>
  </article>
</div>

The card stacks when its container is narrow and goes side-by-side once the container (not the window) passes the @md size.

Why This Matters

Drop that same card into a wide main column and a narrow sidebar. With breakpoints it would behave identically in both because the screen is unchanged — wrong in the sidebar. With container queries it adapts to the space it is actually given, so a component is genuinely reusable anywhere.

You can name containers to query a specific ancestor:

<aside class="@container/sidebar">
  <nav class="@sm/sidebar:flex">…</nav>
</aside>

@sm/sidebar: responds only to the element named sidebar, even with other containers nested around it.

Overflow & Scroll →