Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect prefers-color-scheme change in javascript?

I can use window.matchMedia to detect whether user is in dark mode, but how to listen dark mode change event?

Is there any API like:

window.addEventListener('perfers-color-scheme-change', () => {
  // do something
})
like image 883
AsukaSong Avatar asked Jan 07 '20 03:01

AsukaSong


People also ask

How do you use prefer color schemes?

The prefers-color-scheme CSS media feature is used to detect if the user has requested a light or dark color theme. The user might indicate this preference through an operating system setting (e.g. light or dark mode) or a user agent setting.

What media query property can we use to check if user has chosen the dark mode in their browser or system?

As dark mode is reported through a media query, you can easily check if the current browser supports dark mode by checking if the media query prefers-color-scheme matches at all.


2 Answers

You can add an event-listener with callback on the MediaQueryList returned by Window.matchMedia():

function activateDarkMode() {
  // set style to dark
}

// MediaQueryList
const darkModePreference = window.matchMedia("(prefers-color-scheme: dark)");

// recommended method for newer browsers: specify event-type as first argument
darkModePreference.addEventListener("change", e => e.matches && activateDarkMode());

// deprecated method for backward compatibility
darkModePreference.addListener(e => e.matches && activateDarkMode());

Note: There are two method versions to register an event-listener:

  1. the recommended addEventListener("change", listener)) which allows more fine-grained assignment to event-types
  2. the deprecated addListener(listener)

See also

  • Medium (2019): Use “prefers-color-scheme” to detect macOS dark mode with CSS and Javascript

Thanks to lukaszpolowczyk for pointing out that method addListener(listener) has become deprecated and to AsukaSong for initiating a complete rewrite of this answer.

like image 87
hc_dev Avatar answered Oct 18 '22 03:10

hc_dev


With initialization setter and 'change' listener.

const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
  
const setColorScheme = e => {
  if (e.matches) {
    // Dark
    console.log('Dark mode')
  } else {
    // Light
    console.log('Light mode')
  }
}
  
setColorScheme(colorSchemeQueryList);
colorSchemeQueryList.addEventListener('change', setColorScheme);
like image 32
Kolya_YA Avatar answered Oct 18 '22 01:10

Kolya_YA