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;
}
}
Caveat 1: If a browser you're targeting does not support the
prefers-color-theme
media rule (for example Internet Explorer), auto-detection of the color mode does not work. You need to provide fallback styles in that case instead:// Use light theme by default body { color: black; background: white; // Override in explicit or implicit dark mode @include dark { color: white; background: black; } }
Caveat 2: The mixin prepends your selector with a check for the
data-theme
attribute on the:root
element. That means you cannot use the mixin applied to a selector that already includes the root element:// This results in unmatchable selectors containing :root twice :root .foo { @include dark { background: black; } } // Do this instead: @include dark { .foo { background: black; } }