CSS Container Queries, what are they?
CSS Container queries, what are they?
Intro
Media queries have always been crucial to building web applications. They help make our apps more accessible and easier to use and ensure we reach most of our audience. Media queries have been essential in frontend development to create unique user interfaces.
But now, there’s something new: Container queries.
In this blog post, we’ll explore what Container queries are, how they differ from media queries, and why they’re so amazing.
So, let’s get started!
Refresh on Media queries
Media queries have been available in browsers for a long time, but they didn’t become popular until around 2010 when mobile devices started to take off.
Media queries let us add specific styles based on the type of device, like screens or printers. This is especially helpful for creating modern, responsive apps.
A simple use of Media queries would be changing, for example, a paragraph's font size when the screen width is less than a specific number.
`
In this simple example, when the browser’s viewport width is less or equal to 400px, the font size changes to 8px.
Notice how straightforward the syntax is: we start with the keyword @media, followed by the type of device it should apply to. In this case, we use screen so it doesn’t affect users who print the page—if you don’t add anything, then it falls back to the default, which is “all” including both print and screen. Then we specify a media feature, in this case, the width.
Container queries
Container queries are similar to Media queries. Their main function is to apply styles under certain conditions. The difference is that instead of listening to the viewport of the browser, it listens to a container size. Let’s see this example:
In the above layout, we have a layout with a sidebar and three cards as the content. Using Media queries we could listen to the viewport width and change the layout depending on a specific width. Like so:
`
That’s acceptable, but it requires us to constantly monitor the layout. For example, if we added another sidebar on the right (really weird, but let’s imagine that this is a typical case), our layout would become more condensed:
We would need to change our media queries and adjust their range in this situation. Wouldn’t it be better to check the card container’s width and update its styles based on that? That way, we wouldn’t need to worry about if the layout changes, and that’s precisely what container queries are made for!
First, to define the container we are going to listen to, we are going to add a new property to our styles:
`
The .container class is the one in which our cards reside. By adding the property `container-type, ' we now define this class as a container we want to listen to. We said inline-size as the value to query based on the inline dimensions of the container because we just want to listen to the element's width.
The value of container-type will depend on your use case. If you want to listen to both width and height, then size will be a better fit for you.
You can also have normal as your container-type value, which means the element won’t act as a query container at all. This is handy if you need to revert to the default behavior.
Next, to define our query, we use the new @container CSS at-rule:
`
Notice that it is really similar to how we define our Media queries. Now, if we look at the same screen, we will see the following:
This is very powerful because we can now style each component with its own rules without changing the rules based on the layout changes.
The @container will affect all the defined containers in the scope; we might not want that. We can define the name of our container to specify that we only want to listen to that in specific:
`
We can also have a shorthand to define our container and its name:
`
Container query length units
Container query lengths are similar to the viewport-percentage length units like vh or vw units, but instead of being relative to the viewport, they are to the dimensions of the query container. We have different units, each relative to different dimensions of the container:
- cqw: 1% of a query container's width
- cqh: 1% of a query container's height
- cqi: 1% of a query container's inline size
- cqb: 1% of a query container's block size
- cqmin: The smaller value of either cqi or cqb
- cqmax: The larger value of either cqi or cqb
In our example, we could use them to define the font size of our cards:
`
Using these units alone isn’t recommended because they’re percentage-based and can have a value we don’t want. Instead, it’s better to use a dynamic range. Using the max function, we can set 2 values and always pick the highest one.
Conclusion
Container queries bring a fresh and powerful approach to web design but are not meant to replace Media queries. I think their real power shines when used together.
Media queries often require constant adjustments as your layout evolves. Container queries, however, let you style individual components based on their dimensions, making the designs more flexible and easier to manage.
Adding a new component or rearranging elements won’t force us to rewrite our media queries. Instead, each component handles its styling, leading to cleaner and more organized code.
Please note that, as of writing this blog post, they aren’t compatible with all browsers yet. Take a look at this table from caniuse.com:
A good fallback strategy for this, when hitting an unsupported browser would be the use of the @support rule, which allows you to apply styles only if the browser supports the CSS feature. For example:
`
Ensure your media queries are good enough to keep everything responsive and user-friendly when the condition is unmet.
Thank you for reading! Enjoy the extra flexibility that container queries bring to your web designs. Check out a live demo to see it in action. Happy styling!...