DEV Community

Cover image for Set your Web App to Dark/Light Mode based on User System Settings
Shahid Rizwan
Shahid Rizwan

Posted on

Set your Web App to Dark/Light Mode based on User System Settings

We all know Dark mode is one of the hottest features from 2019. Everything from smartphones, laptops, and your applications now comes with in-build dark mode.

It comes with a lot of advantages. It's the way forward when spending long hours in front of the laptop under low light.

It also saves significant battery in newer devices using OLED screens by turning off the black pixels.

But, is it the best option to choose all the time over light mode? Let's see.

The dark mode comes with some disadvantages too.

Using dark mode when the surrounding is well lit can cause strain to your eyes just like when you use too much light in low light condition. When in the bright surrounding, your eye finds it hard to focus on the content present in the dark background with very little contrast. Therefore, most users switch between dark and light modes in their devices based on their surroundings.

What if, we as developers, can set our web application theme based on the device settings and reduce that extra step to switch in our apps? Will it be possible?
Well, there is a way.

What is Window.matchMedia() ?

Windows.matchMedia() is a method that returns an object that determines if the document matches the media query string.

Just like how we use @media in CSS, you can detect the same media queries in javascript.

For example, if we have the following media query in CSS

@media screen and (max-width:700px){
}
Enter fullscreen mode Exit fullscreen mode

The javascript equivalent is:

const mw = window.matchMedia("screen and (max-width:700px)")
Enter fullscreen mode Exit fullscreen mode

Detecting System theme using matchMedia()

Consider a simple React component with a Hello World text written in it.

function App() {


  return (
    <div>
      Hello World
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

To add the dark mode to the component, we use the prefers-color-scheme CSS media feature. It detects if the system is in a dark theme or light theme.

The matches property of the prefers-color-scheme is a boolean value that updates based on the query.

So, to check the system preference, we add as isDark variable to detect if the system uses dark mode.

function App() {

  const isDark = window.matchMedia("(prefers-color-scheme:dark)").matches

  const lightTheme = {
    backgroundColor : "white",
    color : "black"
  }

  const darkTheme = {
    backgroundColor : "black",
    color : "white"
  }

  return (
    <div style={isDark?darkTheme:lightTheme}>
      Hello World
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Based on the isDark variable value, either the darkTheme or lightTheme syle applies to the component.

Option to Switch themes inside the application

We can also add a toggle inside the application if the user wants to switch between the themes.

For that, we create a state variable and initialize it with the system theme settings.

Every time the user clicks the button, the state variable toggles accordingly.

import { useState } from 'react';

function App() {

  const isSystemDark = window.matchMedia("(prefers-color-scheme: dark)").matches
  const [isDark,setIsDark] = useState(isSystemDark)

  const lightTheme = {
    backgroundColor : "white",
    color : "black"
  }

  const darkTheme = {
    backgroundColor : "black",
    color : "white"
  }

  return (
    <div style={isDark?darkTheme:lightTheme}>
      Hello World
      <button onClick={()=>setIsDark(toggle =>!toggle)}>Switch Theme</button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Discussion (4)

Collapse
madilraza profile image
MUHAMMAD ADIL RAZA

Hey Shahid Rizwan what a Great Peace of Tutorial you are writing .
i want to invite you to My medium Publication to Write your Blogs There and kickstart your Journey There .
medium.com/marsec-developers
this is the Link to our Medium Publication
either you can mail me directly at founder@marsecdev.com
hope to see you soon

Collapse
shaedrizwan profile image
Shahid Rizwan Author

Appreciate it, mate. Will definitely mail you.

Collapse
rbok6 profile image
Mayckoll Abreu

It would be nice if you could add examples in vanilla Javascript.

Collapse
tessy profile image
Tessy • Edited on

Nice script