This is a Sass mixin to handle a 3-way dark mode. It relies on a data-theme attribute on your <html> element with a value of light or dark. If data-theme is absent (i.e. it's neither light nor dark), the system's preferred mode is used.
body {
// matches data-theme="light" or data-theme="auto" with system instructing light mode
@include light {
background: white;
color: black;
}
// matches data-theme="dark" or data-theme="auto" with system instructing dark mode
@include dark {
background: black;
color: white;
}
}See the example above on sassed
Caveat: This mixin targets modern browsers which support the :where() pseudo selector. There is an older revision of this Gist with more caveats, but also with support for older browsers, which you can find here.
@wonsuc Because I changed from nesting to appending. 😁 See the latest revision.
Why do this?
Well, let's say I have a selector
.foowhere I want to use the mixin:This previously generated a selector like
:root.is-dark-mode .foo, usingselector-nest. (This selector is not what it actually generated, which was a little more complex, but it shows what nesting a selector does.)However, this approach created issues when the
.fooselector itself already included the:root, e.g. if you wanted to style something based on a modifier class on the root element, e.g.That would generate
:root.is-dark-mode :root.loading.foo, which would obviously never match as:rootcannot be found inside:root.Therefore, I switched the selector generation over to using the
:where. pseudo class. That feature was not available in browsers when I originally published the gist, that's why I didn't use it in the first place.Now using
selector-appendand:where, the first code sample would generate the selector.foo:where(:root.is-dark-mode *), and the second one would generate:root.loading .foo:where(:root.is-dark-mode *)– which do both work.