Container queries | neoco

/container-queries

Container queries

Marc Amer

Marc Amer

8 min

10/03/2022

A lot of new and amazing CSS properties have already come out, but today we will focus on one in particular, the container queries.

And you may be thinking, how about new CSS properties? Is CSS4 out or something? The answer is: No, CSS4 has not been released.

In another post we will talk about how the new CSS properties and versions are defined. But for now we will tell you that if you see a property that you did not know about on a random page on the internet, the quickest and most direct way to check what that property is for and what support it has is to consult MDN and caniuse.

In MDN we will receive a description of the property, how to use it and a couple of examples. On the other hand, the caniuse website will provide us with a table in which we can check which browsers and their versions support which properties.

And can I already use container queries in production? Don't be impatient, it depends on the environment, but we'll explain this more thoroughly in another article.

container queries caniuse

In this case we can see that there is only full support in Chrome version 106 and Safari version 16.0 and the percentage of global support is around 60%, so in my opinion it is worth waiting a bit to use this new property.

What are container queries?

Well, as its name suggests, it is a property that performs queries, depending on the size or styles of the component defined as a container.

And don't we already have the media queries for that? Yes, but note that I have said that container queries respond to the size or styles of the component defined as a container. This means that you can define as container the parent of your element or another element that contains it that is higher in the DOM tree, instead the media queries only react to the device viewport.

This allows flexibility never seen before for responsiveness in HTML, but especially in React, since you can practically encapsulate your components and have independent elements that behave depending on the environment.

Really cool, but...

How are container queries implemented?

With this short and simple example you can understand it perfectly:

The first step would be to define a component, in this example we will work with a card.

<div class="card-container">
  <div class="card">
    <figure>
      <img
        src="http://static.libsyn.com/p/assets/9/8/1/c/981c2ef87dd4c9e7/TCP000_thumbnail_v3.png"
      />
    </figure>
    <div>
      <div class="meta">
        <h2>Preference Media Queries</h2>
        <span class="time">15:40</span>
      </div>

      <div class="notes">
        <p class="desc">
          In this episode we narrow our focus on user-preference-based media
          queries, which enable you to create personalized experiences based on
          your users custom settings and needs.
        </p>
        <div class="links">
          <h3>Links</h3>
          <ul>
            <li>Media Queries → <a href="#">http://goo.gle/2MhYfR2</a></li>
            <li>Scripting → <a href="#">http://goo.gle/2Mdan5E</a></li>
            <li>
              The 'display-mode' media feature →
              <a href="#">http://goo.gle/2NoFr3c</a>
            </li>
            <li>
              Prefers-* Security and Privacy →
              <a href="#">http://goo.gle/3kfwUM0</a>
            </li>
            <li>
              CSS Color Adjustment → <a href="#">http://goo.gle/3qLkduJ</a>
            </li>
          </ul>
        </div>
      </div>

      <button>Download Episode</button>
    </div>
  </div>
</div>

Demo by Una Kravets

Once we have the component, we have to indicate in the CSS which element will be the container. And we also have to specify the breakpoints that we want the sub-elements of the card to respond to. In the code below you can see that to define a breakpoint you have to do the same as with media queries, but instead of using the word @media, you have to use @container instead.

/* Container definition */
.card-container {
  container-type: inline-size;
}

/* Breakpoints definition */
@container (max-width: 850px) {
  .links {
    display: none;
  }

  .time {
    font-size: 1.25rem;
  }

  h2 {
    font-size: 2.2rem;
  }
}

@container (max-width: 650px) {
  .desc {
    display: none;
  }

  h2 {
    font-size: 2rem;
  }

  .card {
    gap: 1rem;
  }
}

@container (max-width: 460px) {
  .card {
    grid-template-columns: 1fr;
    text-align: center;
    gap: 0.5rem;
  }

  button {
    display: block;
    margin: 1rem auto 0;
  }
}

@container (max-width: 300px) {
  h2 {
    font-size: 1.5rem;
  }

  .time {
    display: none;
  }
}

Demo by Una Kravets

And the result would be this.

horizontal cards

vertical cards

It will be that simple to make the responsive with the container queries.

Resources