Skip to content

Instantly share code, notes, and snippets.

@KarmaBlackshaw
Forked from loilo/readme.md
Created May 5, 2022 10:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KarmaBlackshaw/0fadb7d5c380b0ec60203c6d2c664cfa to your computer and use it in GitHub Desktop.
Save KarmaBlackshaw/0fadb7d5c380b0ec60203c6d2c664cfa to your computer and use it in GitHub Desktop.
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 #{selector-nest(':root:not([data-theme=light]):not([data-theme=dark])', &)} {
@content;
}
}
@at-root #{selector-nest(':root[data-theme=light]', &)} {
@content;
}
}
@mixin dark() {
@media (prefers-color-scheme: dark) {
@at-root #{selector-nest(':root:not([data-theme=light]):not([data-theme=dark])', &)} {
@content;
}
}
@at-root #{selector-nest(':root[data-theme=dark]', &)} {
@content;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment