Sometimes having a light and dark version of the site isn't enough. Sometimes you need light and dark elements, sections or components. Additionally, sometimes you want more than just light and dark.
These nested light and dark scenarios can be tricky.
This post covers 3 strategies: one that can be used today and two that can be used in the future.
Today #
Color-scheme and light-dark() #
With color-scheme
and light-dark()
, the strategy is minimal and effective. One, possibly big, limit is that this is only for color values. But the HTML is clean and tidy.
HTML
<section class="dark">
<h1>Dark</h1>
<section class="light">
<h1>Light</h1>
<section class="dark">
<h1>Dark</h1>
</section>
</section>
</section>
CSS
.dark { color-scheme: dark }
.light { color-scheme: light }
section {
background: light-dark(#ddd, #222);
color: light-dark(#222, #ddd);
}
Can I Use?
Maybe color is all you need to adapt your components and pages. If so, take this code and run!
Future #
@scope #
Miriam Suzanne showed us that a primary use case for @scope
is for scoping light and dark contexts.
They break it down with lots of detail in the @scope Explainer.
I've adapted the demo from this post to use @scope
. The HTML can match the light-dark()
version, but the CSS changes:
@scope (.dark) {
:scope {
color-scheme: dark;
background: #222;
color: #ddd;
border: 5px dashed cyan;
}
}
@scope (.light) {
:scope {
color-scheme: light;
background: #ddd;
color: #222;
border: 5px solid hotpink;
}
}
Can I Use?
We don't get to query or do anything "just in time", but we are able to change colors and any styles we want within a light or dark context.
Style Queries #
But if you want to adapt more than just color in these nested scenarios, then Style Queries and custom properties holding the color-scheme
value can be used.
The HTML does need adjusted though because a style query can only query a parent, so each new context needs wrapped in an element with the .dark
or .light
class.
<div class="dark">
<section>
<h1>Dark</h1>
<div class="light">
<section>
<h1>Light</h1>
<div class="dark">
<section>
<h1>Dark</h1>
</section>
</div>
</section>
</div>
</section>
</div>
.dark, .light {
color-scheme: var(--color-scheme);
}
.dark { --color-scheme: dark }
.light { --color-scheme: light }
section {
background: light-dark(#ddd, #222);
color: light-dark(#222, #ddd);
@container style(--color-scheme: light) {
border: 10px solid pink;
}
@container style(--color-scheme: dark) {
border: 5px dashed cyan;
}
}
Can I Use?
While the HTML is decently less approachable and manageable, it does have some nice benefits.
What strategy are you using?