<main>
  <figure class="post-card">
<!--     <img src="https://picsum.photos/id/64/1560/1024" /> -->
    <figcaption>The Coldest Sunset</figcaption>
    <p class="text-gray-700 text-base">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.
    </p>
  </figure>
  
  <div class="user-toggle">
    <div role="status"></div>
    <button class="toggle-btn">
      <span>Enable</span>
      <span class="toggle-btn__mode">dark</span>
      <span>mode</span>
    </button>
  </div>
</main>
:root {
  --color-mode: 'light';
  --color-light: rgba(0, 0, 0, .75);
  --color-dark: rgba(255, 255, 255, .75);
  --background-light: #f0f2f4;
  --background-dark: #242424;
  --border-light: rgba(0, 0, 0, .33);
  --border-dark: rgba(255, 255, 255, .33);
}

[data-user-color-scheme='light'] {
  --text-color: var(--color-light);
  --background-color: var(--background-light);
  --border-color: var(--border-light);
}

[data-user-color-scheme='dark'] {
  --text-color: var(--color-dark);
  --background-color: var(--background-dark);
  --border-color: var(--border-dark);
}

body {
  padding: 2rem 1rem;
  color: var(--text-color);
  background: var(--background-color);
}

main {
  width: 100%;
  figure {
    margin: 0 auto;
    max-width: 30rem;
    padding: 30px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    margin-bottom: 30px;
    figcaption {
      font-weight: bold;
      font-size: 2rem;
      margin-bottom: 16px;
    }
    p {
      color: var(--text-color);
    }
  }
  
  .user-toggle {
    text-align: center;
    button {
      padding: 8px 12px;
      font-size: 1.25rem;
    }
  }
}

View Compiled
const APP_THEME = 'user-color-scheme'

const toggleButton = document.querySelector('.toggle-btn')
const toggleButtonMode = document.querySelector('.toggle-btn__mode')


const initTheme = () => {
  if (window.matchMedia) {
    const colorSchema  = window.matchMedia('(prefers-color-scheme: dark)')
    
    colorSchema.addListener(e => {
      console.log(e.matches) // Boolean: true/false
      const currentTheme = e.matches ? 'dark' : 'light'
      localStorage.setItem(APP_THEME, currentTheme)
      toggleButtonMode.innerHTML = e.matches ? 'light' : 'dark'
      applyTheme(currentTheme)
    })
    
    // set init theme mode as dark
    localStorage.setItem(APP_THEME, colorSchema.matches ? 'dark' : 'light')
    toggleButtonMode.innerHTML = colorSchema.matches ? 'light' : 'dark'
  }
}

/**
 * if user select the theme, then use the given theme
 */
const applyTheme = givenTheme => {
  let currentTheme = givenTheme || localStorage.getItem(APP_THEME)
  
  if(currentTheme) {
    document.body.setAttribute('data-user-color-scheme', currentTheme)
  }
}

/**
 * get the persistent theme mode, toggle it, then store it.
 */
const toggleTheme = () => {
  let currentTheme = localStorage.getItem(APP_THEME)
  
  switch(currentTheme) {
    case 'light':
      currentTheme = 'dark'
      toggleButtonMode.innerHTML = 'light'
      break
    case 'dark':
      currentTheme = 'light'
      toggleButtonMode.innerHTML = 'dark'
      break
  }

  localStorage.setItem(APP_THEME, currentTheme)
  
  return currentTheme
}

toggleButton.addEventListener('click', e => {
  e.preventDefault()
  
  applyTheme(toggleTheme())
})

initTheme()
applyTheme()

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.