Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <body>

  <h1>Light &amp; dark mode, with user-switch button</h1>

  <p>Inherits dark mode from the OS when enabled, and allows switching in-browser.</p>
  
  <p>Reads the current OS preference and adds an attribute <code>data-lightMode</code> to the <code>&lt;body&gt;</code> tag reflecting its dark or light value. If unsupported in the OS the default is set to light, and switching is still made available. Uses local storage to persist user selection across pages and visits.</p>


  <figure>
    <figcaption>JavaScript added data attribute</figcaption>
    <pre><code class=language-markup spellcheck=false contenteditable>&lt;body data-lightMode="[light | dark]"&gt;</code></pre>
  </figure>


  <figure>
    <figcaption>Set CSS variables for OS light, or no-preference, mode</figcaption>
    <pre><code class=language-css spellcheck=false contenteditable>body {
  --color: hsl(269,19%,30%);
  --bgColor: hsla(32,100%,85%,.35);
  --imgFilter: none;
  --linkColor: hsl(214, 50%, 50%);
  --bgPage: url("data:image/svg+xml;charset=utf8,%3Csvg width='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.4'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
}</code></pre>
  </figure>


  <figure>
    <figcaption>Media query and variables for OS dark mode</figcaption>
    <pre><code class=language-css spellcheck=false contenteditable>@media (prefers-color-scheme: dark) {
  body:not([data-lightMode="light"]) {
    --color: #fafafa; /* Not quite white */
    --bgColor: hsl(269, 19%, 5%);
    --imgFilter: grayscale(10%) brightness(90%);
    --linkColor: hsl(214, 100%, 85%);
    --bgPage: url("data:image/svg+xml;charset=utf8,%3Csvg width='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.4'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
  }
}</code></pre>
  </figure>

  <p><strong>Note:</strong> <code>body:not([data-lightMode="light"])</code> prevents the media query CSS activating while the mode-button is set to light.</p>
  
  <p>We need a second copy of the variables, so the mode-button can also offer dark mode.</p>

  <figure>
    <figcaption>Overwrite OS light mode with dark</figcaption>
    <pre><code class=language-css spellcheck=false contenteditable>body[data-lightMode="dark"] {
  --color: #fafafa; /* Not quite white */
  --bgColor: hsl(269, 19%, 5%);
  --imgFilter: grayscale(10%) brightness(90%);
  --linkColor: hsl(214, 100%, 85%);
  --bgPage: url("data:image/svg+xml;charset=utf8,%3Csvg width='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.4'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
}</code></pre>
  </figure>

  <figure>
    <figcaption>Use the CSS variables</figcaption>
    <pre><code class=language-css spellcheck=false contenteditable>body {
  color: var(--color);
  background-color: var(--bgColor);
  background-image: var(--bgPage);
  transition: 
    background-image .3s ease-out,
    background-color .3s ease-out,
    color .3s ease-out;
}
img:not([src*=".svg"]) {
  filter: var(--imgFilter);
}
a:link,
a:visited {
  color: var(--linkColor);
}</code></pre>
  </figure>



  <h2>Javascript anyone?</h2>

  <p>Local Storage is used to persist the mode selected, light or dark, across pages and visits.</p>

  <figure>
    <figcaption>Supports ES6 &amp; local storage?</figcaption>
    <pre><code class=language-javascript spellcheck=false contenteditable>var supportsES6=(function(){try{new Function('(a=0)=>a');return true}catch(err){console.log('No ES6');return false}}());
var supportsLocalStorage=(function(){try{var m=new Date().valueOf()+"";localStorage.setItem(m,m);localStorage.removeItem(m);return true}catch(e){console.log("localStorage unavailable");return false}}());</code></pre>
  </figure>


  <p>JavaScript adds a mode-toggle button, containing an SVG, to the HTML, which allows the switching of light &amp; dark modes.</p>


  <figure>
    <figcaption>Dark &amp; Light mode toggle button</figcaption>
    <pre><code class=language-javascript spellcheck=false contenteditable>var Dark_Light_Mode_Toggle_Button = (function (window, document, supportsES6, supportsLocalStorage) {

  if (!supportsES6) return;

  const name = 'mode';
  const btnClass = 'actions_btn-' + name;
  const svgClass = 'actions_svg-' + name;
  const clickedClass = '-js-clicked';
  const [light, dark] = ['light', 'dark'];
  const body = document.body;
  const btn = document.createElement('button');

  let mode;

  const _setAttr = (obj, attr, value) =&gt; obj.setAttribute(attr, value);
  const _modeText = bool =&gt; bool ? light : dark;
  const _animEnd = e =&gt; btn.classList.remove(clickedClass);

  const _clicked = _ =&gt; {

    // Note: Pressed state is purposefully not linked to the mode setting.
    // Initially: The mode may be light or dark, but pressed state is always false.
    _setAttr(btn, 'aria-pressed', btn.getAttribute('aria-pressed') === 'false');

    mode = mode === false;

    // Note: color-scheme cannot be set with CSS variables
    // This setting is ignored where unsupported
    body.style.colorScheme = _modeText(mode);

    _setAttr(body, 'data-lightMode', _modeText(mode));
    _setAttr(btn, 'aria-label', `Change to ${_modeText(!mode)} mode`);
    supportsLocalStorage && localStorage.setItem('mode', _modeText(mode));
    btn.classList.add(clickedClass);
    btn.addEventListener('animationend', _animEnd, {once: true});
  };

  // Utilising symbol defs in the HTML
  // [Optionally embed the full SVG here]
  const _getSvg = _ =&gt; `&lt;svg class="${svgClass}" aria-hidden=true focusable=false&gt;
  &lt;use class="${name}-${dark}" xlink:href="#icon-${name}-${dark}"&gt;&lt;/use&gt;
  &lt;use class="${name}-${light}" xlink:href="#icon-${name}-${light}"&gt;&lt;/use&gt;
&lt;/svg&gt;`;

  const _getMode = _ =&gt; {

    // Get the OS mode setting
    mode = (window.matchMedia &amp;&amp; window.matchMedia('(prefers-color-scheme: dark)').matches) ? false : true;

    // Override OS mode with the locally stored value.
    // Caters to state persistence across pages and visits.
    if (supportsLocalStorage &amp;&amp; 'mode' in localStorage) {
      mode = localStorage.getItem('mode') === 'light';
    }
  };

  const _init = _ =&gt; {
    _getMode();

    // Note: color-scheme cannot be set with CSS variables
    // This setting is ignored where unsupported
    body.style.colorScheme = _modeText(mode);

    _setAttr(body, 'data-lightMode', _modeText(mode));
    _setAttr(btn, 'class', btnClass);
    _setAttr(btn, 'aria-pressed', false);
    _setAttr(btn, 'aria-label', `Change to ${_modeText(!mode)} mode`);

    btn.innerHTML = _getSvg();
    btn.addEventListener('click', _clicked);

    // Note: Button is added at the end of the HTML to avoid preceding an accessibility skip-to-content link.
    // Skip-to-content links should always be the first actionable asset on a web page.
    body.appendChild(btn);
  };

  _init();

}(window, document, supportsES6, supportsLocalStorage));</code></pre>
  </figure>


  <p>The property <code class=language-css>color-scheme: [light | dark];</code> informs the browser what modes the page supports, and <strong>may</strong>, where supported (Safari), adjust form controls and scrollbars to suit. Unfortunately, it cannot be set with CSS variables so JavaScript is used.</p>

  <p>
    <label>Select visual for testing:
      <select aria-label="Visual demonstration" role=presentation>
        <option>Unopinionated example</option>
        <option>Unopinionated example</option>
        <option>Unopinionated example</option>
        <option>Unopinionated example</option>
      </select>
    </label>
    <label>Text input visual for testing:
      <input type=text placeholder="Unopinionated example" role=presentation>
    </label>
  </p>

  <h2>Button styling</h2>


  <p>The button styling presented here is not exactly the button used, it omits <a target=_blank title="[new window]" href="https://codepen.io/2kool2/pen/aboydMX">button click animation</a>, but a fully working version none-the-less.</p>


  <figure>
    <figcaption>Basic button styling</figcaption>
    <pre><code class=language-css spellcheck=false contenteditable>button::-moz-focus-inner {
  border: 0;
}
.actions_btn-mode {
  position: fixed;
  z-index: 5;
  top: .5rem;
  right: .5rem;
  width: 3rem;
  height: 3rem;
  border: 0;
  background-color: transparent;
  color: inherit;
}

/* Switch icon between dark &amp; light */
.actions_svg-mode > * {
  transition: opacity .3s ease-out;
}
[data-lightMode="light"] .mode-dark,
[data-lightMode="dark"] .mode-light {
  opacity: 1;
}
[data-lightMode="light"] .mode-light,
[data-lightMode="dark"] .mode-dark {
  opacity: 0;
}</code></pre>
  </figure>


  <figure>
    <figcaption>Light &amp; Dark icons as SVG symbol definitions</figcaption>
    <pre><code class=language-markup spellcheck=false contenteditable>&lt;svg style=display:none id=svg_definitions&gt;
  &lt;defs&gt;
    &lt;symbol viewBox="0 0 960 960" id="icon-mode-dark"&gt;
      &lt;circle cx="476" cy="480" r="458" fill-opacity=".25"/&gt;
      &lt;path d="M382 33C82 91-118 488 115 767c186 223 492 255 716 9a515 515 0 01-421-243c-94-157-56-368-28-500z"/&gt;
    &lt;/symbol&gt;
    &lt;symbol viewBox="0 0 960 960" id="icon-mode-light"&gt;
      &lt;circle cx="479.5" cy="480.5" r="242"/&gt;
      &lt;path d="M480 800c22 0 40 18 40 40v80a40 40 0 01-80 0v-80c0-22 18-40 40-40zm480-320c0 22-18 40-40 40h-80a40 40 0 010-80h80c22 0 40 18 40 40zM706 763l57 56a40 40 0 1056-56l-56-57a40 40 0 10-57 57zm-509 56l57-56a40 40 0 10-57-57l-56 57a40 40 0 1056 56zm-77-379a40 40 0 010 80H40a40 40 0 010-80h80zm21-243l56 57a40 40 0 1057-57l-57-56a40 40 0 10-56 56zm622 57l56-57a40 40 0 10-56-56l-57 56a40 40 0 1057 57zM440 40v80a40 40 0 0080 0V40a40 40 0 00-80 0z"/&gt;
    &lt;/symbol&gt;
  &lt;/defs&gt;
&lt;/svg&gt;</code></pre>
  </figure>
  
  <section>
    <h2>Image example</h2>
    <p>A CSS filter is used to desaturate colour (-15%) and reduce image brightness (-15%) when in dark-mode.</p>
    <img src="https://websemantics.uk/unsplash/red-door.jpg" style="display:block;width:100%;max-width:40rem;margin:2rem auto" alt="Worn and flaky, red painted door - image example for the applied filters"
  </section>


  <h2>References</h2>

  <ul>
    <li><a target=_blank title="[new window]" href="https://hankchizljaw.com/wrote/create-a-user-controlled-dark-or-light-mode/">Create a user controlled dark or light mode</a></li>
    <li><a target=_blank title="[new window]" href="https://web.dev/prefers-color-scheme/">prefers-color-scheme</a></li>
    <li><a target=_blank title="[new window]" href="https://codepen.io/2kool2/pen/MEbeEg">Prism code highlighting (light & dark mode)</a></li>
    <li><a target=_blank title="[new window]" href="https://codepen.io/2kool2/pen/aboydMX">Fixed position animated SVG buttons</a></li>
    <li><a target=_blank title="[new window]" href="https://websemantics.uk/tools/svg-to-background-image-conversion/">SVG to CSS background-image converter</a></li>
<!--
    <li><a target=_blank title="[new window]" href=""></a></li>
-->
  </ul>


<!-- Icon Definitions -->

<svg style=display:none id=svg_definitions>
  <defs>

    <symbol viewBox="0 0 960 960" id="icon-mode-dark">
      <circle cx="476" cy="480" r="458" fill-opacity=".5"/>
      <path d="M382 33C82 91-118 488 115 767c186 223 492 255 716 9a515 515 0 01-421-243c-94-157-56-368-28-500z"/>
    </symbol>
    <symbol viewBox="0 0 960 960" id="icon-mode-light">
      <circle cx="479.5" cy="480.5" r="242"/>
      <path d="M480 800c22 0 40 18 40 40v80a40 40 0 01-80 0v-80c0-22 18-40 40-40zm480-320c0 22-18 40-40 40h-80a40 40 0 010-80h80c22 0 40 18 40 40zM706 763l57 56a40 40 0 1056-56l-56-57a40 40 0 10-57 57zm-509 56l57-56a40 40 0 10-57-57l-56 57a40 40 0 1056 56zm-77-379a40 40 0 010 80H40a40 40 0 010-80h80zm21-243l56 57a40 40 0 1057-57l-57-56a40 40 0 10-56 56zm622 57l56-57a40 40 0 10-56-56l-57 56a40 40 0 1057 57zM440 40v80a40 40 0 0080 0V40a40 40 0 00-80 0z"/>
    </symbol>
  </defs>
</svg>

</body>


<style id=basic_page_styles>
*, *::after, *::before {
  box-sizing: inherit;
}
body {
  font-family: sans-serif;
  text-rendering: optimizeLegibility;
  line-height: 1.5;
  margin: 1rem;
  padding-bottom: 2rem;
  background-attachment: fixed;
}
h1,h2 {
  font-weight: 100;
  margin-top: 2rem;
  margin-bottom: 1rem;
  text-align: center;
}
h1 + p {
  font-size: 1.4rem;
  text-align: center;
}
p {
  font-size: 1.125rem;
}
ul, p {
  max-width: 40rem;
  margin: 1rem auto;
}
li {
  margin:.25rem 0;
}
figure {
  max-width: 40rem;
  margin: 3rem auto;
}
figcaption {
  font-size: 1.25rem;
}
pre {
  overflow: scroll;
  background-color: hsla(0,0%,100%, 0.3);
}
code {
  font-family: monospace, monospace;
  font-size: inherit;
}
label {
  display: block;
  margin: 1rem auto;
  max-width: 24rem;
}
</style>


<style id=action_button_animations>

/* Buttons (or links) */

[class^="actions_btn"],
[class^="actions_btn"]:visited {

  /* button colors light */
  --btn-fg: #503660;
  --btn-bg: #fafafd;
  --btn-fg-hover: #418cec;
  --btn-bg-hover: #fff;

  box-sizing: content-box;
  display: block;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0.25rem;
  color: var(--btn-fg);
  background-color: var(--btn-bg);
  border: 0.125rem solid transparent;
  border-radius: 50%;
  box-shadow: 0 0.25em 0.25em rgba(0, 0, 0, 0.3);
  text-decoration: none;
  outline: 0 solid;
  transition: all 0.3s ease-out;
}
[class^="actions_btn"]:hover,
[class^="actions_btn"]:focus {
  color: var(--btn-fg-hover);
  background-color: var(--btn-bg-hover);
  border-color: var(--btn-fg-hover);
  transform: scale(1.2);
  box-shadow: 0 0.5em 0.5em rgba(0, 0, 0, 0.4);
}
[class^="actions_svg"] {
  width: 2.25rem;
  height: 2.25rem;
  fill: currentColor;
  stroke: currentColor;
  border-radius: 100%;
  overflow: hidden;
  pointer-events: none;
  transition: transform 0.5s ease-out;
}

/* Button click animation */

[class^="actions_btn"].-js-clicked {
  animation: actions_btn-clicked 0.3s ease-out forwards;
}
@keyframes actions_btn-clicked {
  0% {transform: scale(1.2);}
  50% {transform: scale(0.8);}
  100% {transform: scale(1.2);}
}

/* Remove all buttons from printouts */

@media print {
  [class^="actions_container"] {
    display: none !important;
  }
}
</style>




<!-- Codepen footer include -->
[[[https://codepen.io/2kool2/pen/mKeeGM]]]
              
            
!

CSS

              
                /* Global styling is in the HTML so I can include this CSS into other CodePen projects */
body {
  --color: hsl(269, 19%, 30%);
  --bgColor: hsla(32,100%,85%,.35);
  --linkColor: hsla(214, 71%, 47%, 1);
  --linkColorHover: hsla(214, 100%, 35%, 1);
  --linkBgHover: hsla(214, 100%, 85%, 1);
  --linkFocus: hsla(214, 71%, 80%, 0.3);
  --focusOutline: var(--linkFocus) solid 0.25rem;
  --imgFilter: none;
  --bgPage: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.4'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  body:not([data-lightMode="light"]) {
    --color: #fafafa;
    --bgColor: hsl(269, 19%, 5%);
    --linkColor: hsla(214, 100%, 80%, 1);
    --linkColorHover: hsla(214, 100%, 11%, 1);
    --linkFocus: hsla(214, 100%, 80%, .5);
    --focusOutline: hsla(214, 100%, 85%, .6) solid .25rem;
    --imgFilter: grayscale(15%) brightness(85%);
    --bgPage: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.7'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
  }
}
/* Duplicated dark mode for button action */
body[data-lightMode="dark"] {
  --color: #fff;
  --bgColor: hsl(269, 19%, 5%);
  --linkColor: hsla(214, 100%, 80%, 1);
  --linkColorHover: hsla(214, 100%, 11%, 1);
  --linkFocus: hsla(214, 100%, 80%, .6);
  --focusOutline: hsla(214, 100%, 85%, .6) solid .25rem;
  --imgFilter: grayscale(15%) brightness(85%);
  --bgPage: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.7'/%3E%3C/filter%3E%3C/defs%3E%3Crect filter='url(%23a)' opacity='.3' width='100%25' height='100%25'/%3E%3C/svg%3E");
}

body {
  color: var(--color);
  background-color: var(--bgColor);
  background-image: var(--bgPage);
  transition: 
    background-image .3s ease-out,
    background-color .3s ease-out,
    color .3s ease-out;
}

img:not([src*=".svg"]) {
  filter: var(--imgFilter);
  transition: filter 0.3s ease-out;
}

a:link,
a:visited {
  color: var(--linkColor);
  text-decoration-color: var(--linkColorUnderline);
  outline: hsla(214, 71%, 80%, 0); solid .25rem;
  transition:
    color .3s ease-out,
    background-color .3s ease-out,
    outline-color .3s ease-out;
}
a:hover,
a:focus {
  color: var(--linkColorHover);
  outline: var(--linkBgHover) solid .25rem;
  background-color: var(--linkBgHover);
}

button::-moz-focus-inner {
  border: 0;
}
.actions_btn-mode {
  --fromEdge: .5rem;
  position: fixed;
  z-index: 5;
  top: var(--fromEdge);
  right: var(--fromEdge);
  width: 3rem;
  height: 3rem;
  border: 0;
  background-color: transparent;
  color: inherit;
}
@media (min-width: 768px) {
  .actions_btn-mode {
    --fromEdge: 1.5rem;
  }
}

/* Switch icon between dark &amp; light */
.actions_svg-mode > * {
  transition: opacity .3s ease-out;
}
[data-lightMode="light"] .mode-dark,
[data-lightMode="dark"] .mode-light {
  opacity: 1;
}
[data-lightMode="light"] .mode-light,
[data-lightMode="dark"] .mode-dark {
  opacity: 0;
}

/* 
   Includes used:
   Prism highlighting: https://codepen.io/2kool2/pen/MEbeEg
*/
              
            
!

JS

              
                var supportsES6=(function(){try{new Function('(a=0)=>a');return true}catch(e){console.log('No ES6');return false}}());


var supportsLocalStorage=(function(){try{var m=new Date().valueOf()+"";localStorage.setItem(m,m);localStorage.removeItem(m);return true}catch(e){console.log("localStorage unavailable");return false}}());


// Adds a mode toggle button, containing an SVG, to the HTML 
var Dark_Light_Mode_Toggle_Button = (function (window, document, supportsES6, supportsLocalStorage) {

  if (!supportsES6) return;

  const name = 'mode';
  const btnClass = 'actions_btn-' + name;
  const svgClass = 'actions_svg-' + name;
  const clickedClass = '-js-clicked';
  const [light, dark] = ['light', 'dark'];
  const body = document.body;
  const btn = document.createElement('button');

  let mode;

  const _setAttr = (obj, attr, value) => obj.setAttribute(attr, value);
  const _modeText = bool => bool ? light : dark;
  const _animEnd = e => btn.classList.remove(clickedClass);


  const _clicked = _ => {

    // Note: Pressed state is purposefully not linked to the mode setting.
    // Initially the mode may be light or dark, but pressed state is always false.
    _setAttr(btn, 'aria-pressed', btn.getAttribute('aria-pressed') === 'false');

    mode = mode === false;
    body.style.colorScheme = _modeText(mode); // Ignored where unsupported
    _setAttr(body, 'data-lightMode', _modeText(mode));
    _setAttr(btn, 'aria-label', `Change to ${_modeText(!mode)} mode`);
    supportsLocalStorage && localStorage.setItem('mode', _modeText(mode));
    btn.classList.add(clickedClass);
    btn.addEventListener('animationend', _animEnd, {once: true});
  };


// Using symbol defs in the HTML
//   const _getSvg = _ => `<svg class=${svgClass} aria-hidden=true focusable=false>
//   <use class="${name}-${dark}" xlink:href="#icon-${name}-${dark}"></use>
//   <use class="${name}-${light}" xlink:href="#icon-${name}-${light}"></use>
// </svg>`;

  // Using an embedded SVG - So I can include this JS into other CodePen projects
  const _getSvg = _ => `<svg class="${svgClass}" aria-hidden=true focusable=false viewbox="0 0 960 960">
  <g class="${name}-${dark}">
    <circle cx="476" cy="480" r="458" fill-opacity=".25"/>
    <path d="M382 33C82 91-118 488 115 767c186 223 492 255 716 9a515 515 0 01-421-243c-94-157-56-368-28-500z"/>
  </g>
  <g class="${name}-${light}">
    <circle cx="479.5" cy="480.5" r="242"/>
    <path d="M480 800c22 0 40 18 40 40v80a40 40 0 01-80 0v-80c0-22 18-40 40-40zm480-320c0 22-18 40-40 40h-80a40 40 0 010-80h80c22 0 40 18 40 40zM706 763l57 56a40 40 0 1056-56l-56-57a40 40 0 10-57 57zm-509 56l57-56a40 40 0 10-57-57l-56 57a40 40 0 1056 56zm-77-379a40 40 0 010 80H40a40 40 0 010-80h80zm21-243l56 57a40 40 0 1057-57l-57-56a40 40 0 10-56 56zm622 57l56-57a40 40 0 10-56-56l-57 56a40 40 0 1057 57zM440 40v80a40 40 0 0080 0V40a40 40 0 00-80 0z"/>
  </g>
</svg>`;


  const _getMode = _ => {

    // Get the OS mode setting
    mode = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? false : true;

    // Override OS mode with the locally stored value.
    // Caters to state persistence across pages and visits.
    if (supportsLocalStorage && 'mode' in localStorage) {
      mode = localStorage.getItem('mode') === 'light';
    }
  };


  const _init = _ => {

    _getMode();

    // color-scheme cannot be set with CSS variable
    // Ignored where unsupported
    body.style.colorScheme = _modeText(mode);

    _setAttr(body, 'data-lightMode', _modeText(mode));
    _setAttr(btn, 'class', btnClass);
    _setAttr(btn, 'aria-pressed', false);
    _setAttr(btn, 'aria-label', `Change to ${_modeText(!mode)} mode`);

    btn.innerHTML = _getSvg();
    btn.addEventListener('click', _clicked);

    // Note: Button is added at the end of the HTML to avoid preceding an accessibility skip-to-content link.
    // Skip-to-content links should always be the first actionable asset on a web page.
    body.appendChild(btn);
    
  };

  _init();

}(window, document, supportsES6, supportsLocalStorage));


// Includes used:
// Prism highlighting: https://codepen.io/2kool2/pen/MEbeEg

              
            
!
999px

Console