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:
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.
.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.
.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
:
-
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.
.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.
@container cards-container (min-width: 701px) {
}
We can also use the ranged syntax:
/* 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.
.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.
At a width of 1000px and above, it should change to a three-column grid layout.
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.
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.
You can learn more about container queries with these resources:
Top comments (3)
Thank you
Thanks for share with us.
Great article!