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.
You can find this example here.
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:
@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
.
.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:
.container {
container-name: container;
container-type: normal;
/* ... */
}
Create our target element with some color:
h2 {
color: red;
}
And then make a rule for our container:
@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 & mdn.
Top comments (0)