Skip to content

Instantly share code, notes, and snippets.

@loilo

loilo/readme.md

Last active Jul 18, 2020
Embed
What would you like to do?
Sass Dark/Light Theme Mixin

Sass Dark/Light Theme Mixin

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;
  }
}
@mixin light() {
@media (prefers-color-scheme: light) {
@at-root :root:not([data-theme=light]):not([data-theme=dark]) #{&} {
@content;
}
}
@at-root :root[data-theme=light] #{&} {
@content;
}
}
@mixin dark() {
@media (prefers-color-scheme: dark) {
@at-root :root:not([data-theme=light]):not([data-theme=dark]) #{&} {
@content;
}
}
@at-root :root[data-theme=dark] #{&} {
@content;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.