Using CSS size container queries
Tags: css, frontend, webdev
Published: 2023-08-18 17:30:06

CSS size container queries are now fully supported in all major browsers and offer a great way to create responsive page elements.

One advantage of using size container queries is it enables us to place components in different spaces of our web page without needing to know the dimensions of that specific space.

Let’s see how we can use it in creating a responsive card component:
![stacked cards component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5sha3dbxlz4j0gqr4iuw.png)

A rule for using container queries is we cannot style or change the container if we want to measure its dimensions. We can only style its children. In the image above, we are wrapping the `.cards__grid` element with a parent `.cards__container` element so we can style the grid and all its contents.

**1. The first step is to define the element we want to get the dimensions of by using the `container-type` property**. 

Here we are making the `.cards__container` element as our containment context so we can query its width.
```css
.cards__container {
    container-type: inline-size;
}
```


The values for the `container-type` property can either be:
* `size` - query the height and width of the container. 

When we make an element the containment context, the built-in dimensions of its content is ignored so the container loses its height. Its width will not be affected because width is an extrinsic size of a block element. They always occupy the entire width of the space.
```css
.cards__container {
    container-type: size;
}
```
See how the pink-bordered `.cards__container` element is no longer stretching the full height of its content after changing the value of `container-type` to `size`:
![stacked cards component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ajdhxqxi0fzq4pef88n8.png)


* `inline-size` - only query the width. This is the recommended value for full responsiveness.
* `normal` - doesn't allow us to query the dimensions but allows us to query the styles.

Naming the container is also considered a best practice. We can think of the name as a class or ID and we can give multiple names to a container.
```css
.cards__container {
    container-type: inline-size;
    container-name: cards-container;
}
```


**2. After defining and naming the container, we can add our query.**
We start the query with the `@container` at-rule followed by the name. Similar to media queries, we can use the `min-width` or `max-width` properties for the condition.
```css
@container cards-container (min-width: 701px) {

}
```

We can also use the ranged syntax:
```css
/* if the width is between 700 and 1000 pixels. */
@container cards-container (700px < width < 1000px) {

}
```

**3. Finally, we can add the style rules for the children of the container**.

```css
.cards__container {
  container-type: inline-size;
  container-name: cards-container;
}

@container cards-container (min-width: 701px) {
  .cards__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .card figure {
    display: block;
  }

  .card__text {
    margin-top: 1rem;
  }

  .card h3 {
    font-size: 1.8rem;
  }

  .card figcaption {
    font-size: 1.2rem;
  }
}

@container cards-container (min-width: 1000px) {
  .cards__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
```

Now, our `.cards__grid` element should switch to a two-column grid layout when the container is more than 700px wide, the image stacked on top of the text and the font-size bigger.
![two-column cards grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qh24fgxddlfx9ggdjjdz.png)

At a width of 1000px and above, it should change to a three-column grid layout.
![three-column cards grid](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7uwyyafcilaf3haon4sn.png)

## Why use size container queries over media queries?

At the beginning of this article we mentioned that size container queries allow us to place elements anywhere on the page without worrying about the size of the space.

To demonstrate this more clearly, let's place the card component in a blog page that has a narrower `<main>` element. With media queries, the cards' layout will stay as a three-column grid because we are checking for the page's width instead of the container's.
![blog page with cards](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hk0iup8ci9zqlblky10.png)

We will need to override the styles of the cards that are in the blog page to correct this.

With container queries, the cards component is more reusable and responsive. The cards' grid will respond to the width of its container and will update to the stacked layout. 
![blog page with cards](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvzair2ukgl04jccnx83.png)

You can learn more about container queries with these resources:
- [MDN docs - CSS container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries)
- [A Primer on CSS Container Queries](https://www.smashingmagazine.com/2021/05/complete-guide-css-container-queries/)
- [Container queries land in stable browsers](https://web.dev/cq-stable/)