home ~ projects ~ socials

Switch A Stylesheet Based Of Local Storage

NOTE:

The goal of this is to switch out a stylesheet without a flash of unstyled content (FOUC). Specifically, the goal is to be able to set either light or dark mode and hit the page and see that mode without seeing a flash of the other mode.

Notes

These are some things I had to do to get the FOUC to go away.

  • Add defer to the script tags in the head

Output

Testing Mode Switch

HTML

<fieldset>
  <legend>Testing Mode Switch</legend>
  <div>
    <input 
      type="radio" 
      id="switch_is_dark" 
      name="test_mode_switch" 
      value="dark" 
      checked />
    <label for="switch_is_dark">Dark</label>
  </div>
  <div>
    <input 
      type="radio" 
      id="switch_is_light" 
      name="test_mode_switch" 
      value="light" />
    <label for="switch_is_light">Light</label>
  </div>
</fieldset>
function logSwitchState(event) {
  let value = event.target.value
  console.log(`Switch is now ${value}`)
  localStorage.setItem("post-2n7kjbnu-switch", value)
  if (value === "light") {
    console.log("LIGHT")
    var link = document.createElement( "link" );
    link.href = "/theme/styles/variables-alt.css";
    link.type = "text/css";
    link.rel = "stylesheet";
    link.media = "screen,print";
    document.getElementsByTagName( "head" )[0].appendChild( link );
  } else {
    console.log("DARK")
    var link = document.createElement( "link" );
    link.href = "/theme/styles/variables.css";
    link.type = "text/css";
    link.rel = "stylesheet";
    link.media = "screen,print";
    document.getElementsByTagName( "head" )[0].appendChild( link );
  }
}

document.addEventListener("DOMContentLoaded", () => {
  const buttons = 
    document.querySelectorAll('input[name="test_mode_switch"]')
  buttons.forEach((btn) => {
    btn.addEventListener(
      "input", 
      logSwitchState
    )
  })
})

console.log("xxxx")
<!-- load light mode first so it's easier to see a flash -->

<link rel="stylesheet" href="/theme/styles/variables-alt.css" />
<link rel="stylesheet" href="/theme/styles/theme.css" />

<script type="text/javascript">
const themeState = localStorage.getItem("post-2n7kjbnu-switch")
if (themeState === "dark") {
  var link = document.createElement( "link" );
  link.href = "/theme/styles/variables.css";
  link.rel = "stylesheet";
  document.getElementsByTagName( "head" )[0].appendChild( link );
}
</script>
-- end of line --