DEV Community

Cover image for Dark theme only CSS, Media Query and also with Javascript
German P
German P

Posted on

Dark theme only CSS, Media Query and also with Javascript

Code:Github repo
codepen: Con js y css
codepen: solo css

Installation

It can be run from any virtual server you have, this point is not 100% necessary.

First clone the repository and install.

git clone https://github.com/205mdp/html-css-js-dark-light-theme.git

yarn add 
Enter fullscreen mode Exit fullscreen mode

Run

yarn dev
Enter fullscreen mode Exit fullscreen mode

Option 1 - only css

  • Generate variables that are assigned to the background and colors.

Documentation CSS Variables

/* just variable example */
body {
  /* create variable  */
  --main-back-color: red;
  /* assign variable  */
  background-color: var(--main-back-color); 
}
Enter fullscreen mode Exit fullscreen mode
  • Generate media query.
:root {
  --background: white;
  --color: black;
}

/* media query dark  */
@media (prefers-color-scheme: dark) {
  :root {
    --background: black;
    --color: white;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Conclusion: This simple step takes the browser theme and applies it to the page.

Option 2 With Javascript and media query

We detect what configuration the system has.

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
    localStorage.setItem('theme', 'dark');
} else {
    localStorage.setItem('theme', 'light');
}
Enter fullscreen mode Exit fullscreen mode

Schema color change event

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
  event.matches ? enableDarkMode() : disableDarkMode();
});
Enter fullscreen mode Exit fullscreen mode

Option 3 With Javascript manually by button.

It can be done by adding a class to the body .dark , .light we save it in the localStorage too.

// Change from dark mode to light mode. 
const enableDarkMode = () => {
  document.body.classList.add('darkmode');
  // 2. Update darkMode in localStorage
  localStorage.setItem('theme', 'dark');
}
// change from light mode to dark mode.
const disableDarkMode = () => {
  // 1. Remove the class from the body
  document.body.classList.remove('darkmode');
  // 2. Update darkMode in localStorage 
  localStorage.setItem('theme', 'light');
}

Enter fullscreen mode Exit fullscreen mode

Button event

// btn btn-theme
const btnTheme = document.querySelector('#btn-theme');

btnTheme.addEventListener('click', () => {
  // 1. Check if dark mode is enabled
  localStorage.getItem('theme') === 'dark' ? disableDarkMode() : enableDarkMode();

})
Enter fullscreen mode Exit fullscreen mode

Note: There is a better solution to not duplicate both css variables and classes. Which is controlling from JS. We see it in the next branch.

With Javascript but without media query

  • The .lightmode class is removed and the @media (prefers-color-scheme: dark) is removed, everything is done with Javascript and stored in the LocalStorage.

  • From css we only have the variables in the root and in the .darkmode class, the .darkmode class is assigned to the body and is removed when it is in light mode, the base root variables being applied.

/* global variables */
:root {
  --header-color: #f5f5f5;
  --header-back-color: rgb(84, 121, 241);
  --main-back-color: #f5f5f5;
  --main-color: #333;
  --header-container-max-width: 70rem;
}

.darkmode {
  --header-color: #b2b2b2;
  --header-back-color: rgb(31, 31, 31);
  --main-back-color: #595959;
  --main-color: rgb(235, 235, 235);
  --header-container-max-width: 70rem;
}
Enter fullscreen mode Exit fullscreen mode
  • When the page loads we check which theme is on the system and which theme is on the local host. Leave the one found on Localhost.
// Detect system color
const detectColorScheme = () => {
  const localTheme = localStorage.getItem('theme');
  // Check which theme the system/browser has 
  if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
    (localTheme === 'dark' || localTheme === null) ? enableDarkMode() : disableDarkMode();
  } else {
    (localTheme === 'dark') ? enableDarkMode() : disableDarkMode();
  }
}

// Check for changes to the theme and change it
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
  event.matches ? enableDarkMode() : disableDarkMode();
});

// Detect system color
detectColorScheme();

Enter fullscreen mode Exit fullscreen mode
  • Here, finally, the auxiliary functions and the control of the button to change the theme, between dark and light.
// btn btn-theme
const btnTheme = document.querySelector('#btn-theme');

btnTheme.addEventListener('click', () => {
  // 1. Check if dark mode is enabled
  localStorage.getItem('theme') === 'dark' ? disableDarkMode() : enableDarkMode();

})

// Change from dark mode to light mode. 
const enableDarkMode = () => {
  document.body.classList.add('darkmode');
  // 2. Update darkMode in localStorage
  localStorage.setItem('theme', 'dark');
}
// cambio de light mode a dark mode.
const disableDarkMode = () => {
  // 1. Remove the class from the body
  document.body.classList.remove('darkmode');
  // 2. Update darkMode in localStorage 
  localStorage.setItem('theme', 'light');
}

Enter fullscreen mode Exit fullscreen mode

Final note: you could add more color themes or let the client select the colors and save them to localstorage or the database.


Each point is a different branch on github

Discussion (0)