Container Queries
Container queries provide the ability to add conditional styles, including conditionally adding styles based on other computed styles.
Introduction to Container Queries
Containers and container queries are a conceptual extension on what you may be familiar with from using @media queries for responsive styling. The difference is that the conditions come from the closest containment ancestor, instead of viewport size.
General CSS Container Query Syntax:
@container (width > 400px) {
h2 {
font-size: 1.5em;
}
}
You can even name containers to specify which type of ancestor to look for in your queries.
CSS container queries on MDN
@container on MDN
Container Style Queries
To solve the original question, use container style queries, where your conditional styles come from computed style conditions.
Example Solution
.my-container {
/* This is the ancestor that sets the CSS style containment context. */
/* - I've provided it an name, `my-container`, that can optionally be used to filter your `@container` query */
container: my-container;
}
/* This is your condition */
/* - Boolean logic and comparisons of any style, color, and custom property are supported. */
/* - You can even compare variables using `style(--button-color: var(--brand-color))` */
@container style(--is-dark-theme: 1) {
.my-conditionally-styled-element {
/* And here's your conditional style. */
/* Want an else case? Use the CSS cascade! For instance, use the same selector above the conditional style to provide a default. */
border: 1px solid;
}
}
<div class="my-container" style="--is-dark-theme: 1">
<p class="my-conditionally-styled-element">My closest container is in dark theme!</p>
</div>
<div class="my-container" style="--is-dark-theme: 0">
<p class="my-conditionally-styled-element">My closest container is in light theme!</p>
</div>
Learn more about container style queries on MDN
Important Implementation Considerations
- The style query is evaluated on the container, not the selectors inside the query. If you would like to compare two variables and one of them is on the same element as you'd like to apply your styles, consider moving the variable to a wrapper element and making the wrapper a
container.
- The container must be an ancestor with a containment context. If you don't already have a parent with a CSS
container, consider the default value of container-type: normal which enables style query containment without the side effects of container size queries that you may find from popular examples that use a value like inline-size.
- To compare colors, you may need a valid
@property definition (syntax: "<color>";, inherits, and initial-value) for your variable.
- Browser support for container queries is "Baseline 2023 - Newly available". If this is more restrictive than your target browser list, you may need to limit your usage to progressive enhancement or consider another option.
if() Function in CSS
Chromium 137 shipped an if() function in CSS that also can use style queries but works inline. Browser support is even lower and it's still experimental at the time of writing this update, so pay special attention to adding an explicit fallback if you try them out.
The if() statement does not gracefully degrade; an explicit fallback needs to be provided for non-supporting browsers.
- MDN
If you use it exclusively for progressive enhancement or the browser support isn't an issue for your use case, if() has some strengths that may make it a good option:
.my-conditionally-styled-element {
/* Make sure to add a fallback for when `if()` is not supported */
border: none;
/* Conditional style */
border: if(
style(--is-dark-theme: 1): 1px solid;
else: none;
);
}
<p class="my-conditionally-styled-element" style="--is-dark-theme: 1">I am in dark theme!</p>
<p class="my-conditionally-styled-element" style="--is-dark-theme: 0">I am in light theme!</p>
Learn More about CSS if() on MDN