How to make your websites even more responsive!
Tags: webdev, css, javascript, programming
Published: 2022-11-27 17:18:24

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eip9zl0gsfzergl58rg4.png)

You can find this example [here](https://codepen.io/milansav/pen/WNyygbv).

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

```
@container <condition> {
  <style>
}
```

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>
}
```

Practical example of this could be:

```css
@container (width > 400px) and (width < 500px) {
  h2 {
    background-color: red;
  }
}
```

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`.
```css
.container {
}
```

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:
```css
.container {
  container-name: container;
  container-type: normal;
  /* ... */
}
```

Create our target element with some color:

```css
h2 {
  color: red;
}
```

And then make a rule for our container:

```css
@container container style(background-color: red) {
  h2 {
    color: white;
  }
}
```

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>
  }
}
```

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](https://w3c.github.io/csswg-drafts/css-contain-3/#container-rule) & [mdn](https://developer.mozilla.org/en-US/docs/Web/CSS/@container).