There are 0 items you can search

CSS Container Queries for responsive components

Use container queries to style elements based on their own container size instead of the full browser width.

They are useful for cards, sidebars, widgets, grids, tool panels, and reusable layout blocks.

This page keeps it practical with simple examples you can understand and adapt quickly.

CSS container queries let a component respond to the size of its parent container. Instead of asking “how wide is the browser?”, you can ask “how wide is this card area, sidebar, widget, or layout block?”

Media queries are based on the viewport. That works for full-page layouts, but it is not always enough for reusable components. A card might appear in a wide main column, a narrow sidebar, or a small grid cell. Container queries let the card adapt to the space it actually has.

First, define a container. Then use @container to change the child styles when that container reaches a certain width.

<div class="card-wrap">
  <article class="demo-card">
    <h2>Responsive card</h2>
    <p>This card changes based on its container width.</p>
  </article>
</div>

<style>
.card-wrap{
  container-type:inline-size;
}

.demo-card{
  border:2px solid #111;
  border-radius:14px;
  padding:16px;
  background:#fff;
}

@container (min-width:500px){
  .demo-card{
    display:grid;
    grid-template-columns:160px 1fr;
    gap:16px;
  }
}
</style>

Naming a container makes your CSS clearer, especially when a page has multiple containers.

<div class="product-area">
  <article class="product-card">
    <h3>Simple product card</h3>
    <p>The layout changes when the product area gets wider.</p>
  </article>
</div>

<style>
.product-area{
  container-name:product;
  container-type:inline-size;
}

.product-card{
  border:2px solid #111;
  border-radius:14px;
  padding:16px;
}

@container product (min-width:600px){
  .product-card{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:18px;
  }
}
</style>

Container queries are great when the same card can appear in different parts of a layout.

<div class="card-container">
  <div class="feature-card">
    <strong>Fast setup</strong>
    <p>Drop this component into a narrow or wide area.</p>
  </div>
</div>

<style>
.card-container{
  container-type:inline-size;
}

.feature-card{
  border:2px solid #111;
  border-radius:14px;
  padding:14px;
  background:#fff;
}

.feature-card strong{
  display:block;
  font-size:18px;
}

@container (min-width:420px){
  .feature-card{
    padding:20px;
  }

  .feature-card strong{
    font-size:24px;
  }
}

@container (min-width:700px){
  .feature-card{
    display:grid;
    grid-template-columns:1fr 2fr;
    gap:20px;
  }
}
</style>

Container query units let you size things based on the container instead of the viewport. The most useful one is often cqw, which means one percent of the container width.

<div class="headline-wrap">
  <h2>Fluid component headline</h2>
</div>

<style>
.headline-wrap{
  container-type:inline-size;
}

.headline-wrap h2{
  font-size:clamp(20px, 8cqw, 42px);
  line-height:1.1;
}
</style>

This is where container queries shine. The same widget can work in a narrow sidebar or a wide content area without writing separate page-specific CSS.

<aside class="widget-zone">
  <div class="profile-widget">
    <div class="avatar"></div>
    <div>
      <strong>Widget title</strong>
      <p>This layout changes when the widget zone has room.</p>
    </div>
  </div>
</aside>

<style>
.widget-zone{
  container-type:inline-size;
}

.profile-widget{
  border:2px solid #111;
  border-radius:14px;
  padding:14px;
}

.avatar{
  width:52px;
  height:52px;
  border-radius:50%;
  background:#ddd;
  margin-bottom:10px;
}

@container (min-width:380px){
  .profile-widget{
    display:flex;
    align-items:center;
    gap:14px;
  }

  .avatar{
    margin-bottom:0;
    flex:0 0 auto;
  }
}
</style>

Responsive cards, reusable widgets, sidebars, dashboard panels, tool result boxes, profile cards, pricing tables, embedded components, product cards, content blocks, and layouts where a component should respond to its own available space.

Forgetting to set container-type, placing the @container rule on the same element you are trying to query, using container queries when a normal media query is simpler, or trying to use them for JavaScript behavior instead of CSS styling.

Media queries respond to the browser viewport. Container queries respond to a component’s container. Use media queries for full-page layout changes. Use container queries when a reusable block needs to adapt to whatever space it is placed inside.

Container queries are best when CSS needs to change the layout or styling. ResizeObserver is best when JavaScript needs to know the element size, such as resizing a chart, updating a canvas, changing a label, or running custom logic.

Use CSS container queries when a component should look different depending on the space around it. They are especially useful for reusable components that may appear in different layouts across the same site.

Container queries help you build smarter responsive layouts with plain CSS. For VibeScriptz-style pages and tools, they are useful because they reduce page-specific CSS and make reusable components easier to maintain.

CSS container queries handle component styling based on container size. ResizeObserver handles JavaScript reactions to element size. CSS clamp() handles fluid font sizes and spacing. content-visibility helps browsers skip rendering work for off-screen content.

If you need JavaScript to detect element size changes, read the ResizeObserver guide. If you need to detect visibility, read the Intersection Observer guide. If you need to detect DOM changes, read the MutationObserver guide.

Read the full guide on MDN Web Docs.

content visibility, CSS clamp, fluid typography, responsive images, modern CSS grid, subgrid, and component-based CSS would all connect well to this topic.