Rethink RWD through CSS Container Queries

Introduction

I first heard the term CSS Container Queries🔗 a year or two ago. As web evolves, I am increasingly convinced that this technology will be an important piece for future Responsive web design. This article will introduce the shortcomings of existing Media Queries🔗 and the advantages of the new solution.

Differences between Media Queries and Container Queries

When it comes to RWD, Media Queries usually come to mind. Both old and new properties provide different solutions typically used to address “style switching of UI fragments on different device sizes.” For example, the thinking behind writing RWD using Media Queries is:

Use style y when the current device size is x.
  • I want to collapse the menu on small devices and expand (hide) it on large devices.
  • I want to display 1 column on small devices but 3 columns on large devices (change layout).

Noted that the focus is on observing changes in device size and applying different styles. This method of creating RWD web pages has accompanied us for a long time, but what if we want the style change to occur on specific web elements? Relying solely on device size to change styles becomes insufficiently flexible.

With the development of web componentization, we tend to build web components that flexibly adapt to various device sizes rather than emphasizing specific designs for specific devices as in early AWD🔗. This is also why, despite having Media Queries, there is still a need to introduce Container Queries—“observing changes in specific web elements and applying different styles,” which means:

Element x uses style z when at size y.

How to Use Container Queries

With Container Queries, developers can truly define styles for individual web elements. It provides greater flexibility to choose which element size to observe and apply styles when conditions are met.

First, you need to define a non-inline element as a “container.” By default, no element is a container, allowing you to control which element is the “container.”

inline-size vs size

When you define a container context, you will use the container-type property and give it a value of inline-size or size. The default value of this property is normal, and it can also be set to cancel the container when needed.

  • inline-size: The width of the container is determined by the container, and the height is determined by the content.
  • block-size: Both the height and width of the container are determined by the container; if not set, it defaults to 0.

Most of the time, specifying the height of the container is meaningless because the height is usually determined by the content, so the vast majority will only use the inline-size property to set the container.

.container-element {
container-type: inline-size;
}

Default Usage

Once a container is set, the new @container can be used on any element within the container.

@container (min-width: 30em) {
.child-element {
font-size: 1rem;
}
}

Naming Containers

If there are many containers, giving them names is a clear way to specify a container. While not absolutely necessary, it defaults to targeting the nearest parent container.

.container-element {
container-name: card;
container-type: inline-size;
/* Shorthand as follows */
container: card / inline-size;
}

You can directly reference named Container Queries in your queries.

@container card (min-width: 50em) {
.child-element {
font-size: 1rem;
}
}

Container Query Length Units

You can use Container Query Length Units🔗 within a container to obtain information related to the container, such as its width and height.

  • cqw🔗: 1% of the Query Container’s width
  • cqh🔗: 1% of the Query Container’s height
  • cqi🔗: 1% of the Query Container’s inline size
  • cqb🔗: 1% of the Query Container’s block size
  • cqmin🔗: 1% of the smaller value between the container’s inline size or block size
  • cqmax🔗: 1% of the larger value between the container’s inline size or block size

Container Queries Do Not Replace Media Queries

Since Container Queries can more flexibly select elements on a webpage, what reason is there to use Media Queries? In fact, the two are not replacements but complementary; in certain cases, you will still need to adjust styles based on device size. For example: using Media Queries to adjust global variables across the entire webpage. The following example demonstrates using Media Queries to change global CSS variables, with many possibilities beyond color: font size, spacing, etc., closely related to device size.

:root {
--bg-color: red;
}
@media (800px < width) {
:root {
--bg-color: green;
}
}

Summary

  • Media Queries: Easy to specify overall page styles
  • Container Queries: Easy to specify styles for individual elements at different sizes

I highly recommend Ahmad Shadeed’s article: An Interactive Guide to CSS Container Queries🔗 which includes interactive teaching examples and all common Container Queries application scenarios.

Further Reading