DEV Community

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

Posted on

2 1

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

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay