Container query card ⚠️

Container query card ⚠️

Warning: This demo uses an experimental web technology that is not currently supported in all browsers. To try it out, open Chrome Canary and enable the #enable-container-queries flag.

This demo uses container queries to create an intrinsic, responsive card. The card goes from a single-column layout at more narrow sizes to a two-column layout when it is at wider sizes.

To create the container, first set containment on the parent:

/* Set containment on parent */
.container {
container: inline-size;
}

You can set some base styles:

.desc {
display: none;
}

.card {
text-align: center;
padding: 0.5rem;
}

And update those base styles according to that parent container's inline width:

/* 2-column grid layout at >=350px */
@container (min-width: 350px) {
.card {
display: grid;
grid-template-columns: 40% 1fr;
align-items: center;
gap: 1rem;
text-align: left;
}
}

/* Display description at >=500px */
@container (min-width: 500px) {
.desc {
display: block;
}
}

This means that if you have this exact same component in different parts of your UI, it's able to use its own logic to resize and best fit its container. You have better control over the card's layout than you would if you only had the global viewport to rely on. The following illustrates this by placing the container query card in a grid with varying column widths:

Explore this Demo on Codepen

<div class="container">
  <div class="card">
    <div class="visual"></div>
    <div>
      <div class="meta">
        <h1>Card Title Here</h1>
        <h2 class="time">Subtitle</h2>
      </div>
        <p class="desc">Here is some descriptive text to support the main idea of the card. It will be hidden when there is less inline space.</p>
      <button>I'm a button</button>
    </div>
  </div>
</div>
/* Set containment on parent */
.container {
  container: inline-size;
  width: 100%;
  max-width: 750px;
  margin: 0 auto;
}

/* Base Styles */
.visual {
  aspect-ratio: 1 / 1;
}

.desc {
  display: none;
}

.card {
  text-align: center;
  padding: 0.5rem;
}

/* Responsive styles */

/* 2-column grid layout at >=350px */
@container (min-width: 350px) {
  .card {
    display: grid;
    grid-template-columns: 40% 1fr;
    align-items: center;
    gap: 1rem;
    text-align: left;
  }
}

/* Display description at >=500px */
@container (min-width: 500px) {
  .desc {
    display: block;
  }
}
Last updated: Improve article