DEV Community

Milanin
Milanin

Posted on

How to make your websites even more responsive!

We've all had to make our sites responsive at some point.
Flexbox, grid, and @media queries are pretty much the standard options for most of the developers out there.

Some of you might have even had to change an element's style based on its container size using JavaScript. But did you know, you could avoid all that hassle with one css at-rule?

Today I'm going to introduce you to the CSS @container rule.

This rule is very similar to the @media rule, however, while @media triggers style changes based on media properties, the @container triggers style changes based on parent container properties.

Where I see the opportunity to use this rule is in uncluttering or even removing content from small, cramped cards.

Image description

You can find this example here.

The syntax for the @container rule is the same as for the @media rule.

@container <condition> {
  <style>
}
Enter fullscreen mode Exit fullscreen mode

The condition supports the following descriptors: aspect-ratio, orientation, block-size, height, width, and inline-size.
Most of the descriptors speak for themselves, however, with orientation, I want to mention, that it's not dependent on the orientation of your device, but rather on the aspect-ratio of the parent container, eg., if width is greater than height, the orientation is landscape in the opposite case portrait.

You can combine multiple conditions with keywords like and, or, and not.

@container <cond> and <cond> or <cond> not <cond> {
  <styles>
}
Enter fullscreen mode Exit fullscreen mode

Practical example of this could be:

@container (width > 400px) and (width < 500px) {
  h2 {
    background-color: red;
  }
}
Enter fullscreen mode Exit fullscreen mode

This means that h2's background color will be set to red when its parent container's width is greater than 400 px and less than 500 px.

Let's have a look at how you can define a container with some properties.

Let's say we currently have an empty class .container.

.container {
}
Enter fullscreen mode Exit fullscreen mode

You can specify the container's name and behavior with
either the container-name and container-type properties.
or container: container-name / container-type (which hasn't worked for me for some reason but the long version works flawlessly!).

Values available for container-type are size, inline-size, and normal.

Container type size lets you query a container's size in both block and inline dimensions, inline-size lets you query a container's size only in, as the name might suggest, the inline dimension, and normal doesn't let you query a container's size, only its style.

I haven't mentioned this up until now, but you can also use the parent container's style in your conditions!

Let's make a container, without any size available:

.container {
  container-name: container;
  container-type: normal;
  /* ... */
}
Enter fullscreen mode Exit fullscreen mode

Create our target element with some color:

h2 {
  color: red;
}
Enter fullscreen mode Exit fullscreen mode

And then make a rule for our container:

@container container style(background-color: red) {
  h2 {
    color: white;
  }
}
Enter fullscreen mode Exit fullscreen mode

This is called style query, if our container has at some point its background color set to red, we can avoid our h2 blending in with the background.

I should also mention that you can also nest containers inside of each other, like shown here:

@container <condition> {
  @container <condition> {
    <style>
  }
}
Enter fullscreen mode Exit fullscreen mode

According to caniuse.com @container is currently supported by 73% of all browsers (firefox & safari < 16 don't support it). So for the most part, unless your target is 100% support, you don't need to worry as much about browser compatibility.

There is so much more to @container rule than I can possibly cover here. If you're interested and want to find out more, check out these sites w3c & mdn.

Top comments (0)