Tailwind CSS v4 Container Queries for Components That Travel

Viewport breakpoints layout the page. Container queries let a card adapt to its slot. Tailwind v4 makes that first-class—here is the mental model.

Design workspace with layouts on screen

Tailwind CSS v4 Container Queries for Components That Travel

For a decade, responsive design mostly meant viewport media queries. That
works for headers and page grids. It fails for reusable components: the same
card in a wide main column and a narrow sidebar should not both wait for
lg: on the window.

CSS container queries fix that. An element styles itself based on the
size of a parent container. Tailwind CSS v4 brings this into core—no
@tailwindcss/container-queries plugin required.

The two-layer mental model

Layer Tool Question it answers
Page chrome sm: md: lg: How should the layout shell change with the device?
Component guts @sm: @md: @lg: How should this widget change with its slot width?

Nav collapse, sidebar visibility, and multi-column page grids stay on
viewport variants. Card internals, comment widgets, and pricing tiles move
to container variants so they remain portable.

Minimal pattern

<article class="@container">
  <div class="flex flex-col gap-4 @md:flex-row @md:items-center">
    <img class="w-full @md:w-40" src="..." alt="" />
    <div>
      <h3 class="text-lg @md:text-xl">Title</h3>
      <p class="text-sm @lg:text-base">Summary…</p>
    </div>
  </div>
</article>

Mark a parent with @container, then swap md: for @md: on children.
Remember: container breakpoint scales differ from viewport scales
(@md is typically narrower than md). Tune via @theme if your design
tokens demand it.

Nested layouts: name the container

When containers nest, query a specific ancestor:

<div class="@container/main">
  <aside class="@container/sidebar">
    <div class="@md/sidebar:block @md/main:hidden">…</div>
  </aside>
</div>

Gotchas that waste afternoons

  1. Unsized parents. A flex child without a real width may report 0 for
    container queries. Ensure the container establishes inline size.
  2. Hiding the container. display: none on the @container itself
    collapses measured width—hide an outer wrapper instead.
  3. Mixing layers carelessly. Do not “fallback” @md: with md: on the
    same property unless you intentionally want both page and slot rules.

Why this matters for Django + Tailwind sites

Server-rendered partials (and HTMX swaps) drop the same component into
different regions. With container queries, the browser re-resolves styles
when the slot changes—no prop-drilled size="compact" variants, no
Alpine watchers for width.

Ship page structure with classic breakpoints. Teach components to respect
their container. That split is the durable responsive architecture Tailwind
v4 finally makes convenient.

Share

Pass this post along on Telegram, WhatsApp, or copy the link.

Telegram WhatsApp

Keep Reading

Related Posts

More Writing

Explore the full blog

Browse more articles on backend systems, APIs, and building reliable products.

All Posts