Hemanth.HM

A Computer Polyglot, CLI + WEB ♥'r.

Detect Dark Mode

| Comments

Detecting if the user preference is light or dark color theme is pretty easy with the prefers-color-scheme CSS media feature, below code gives more details on the same.

Detecting the prefered color scheme in JS:

1
2
const isDarkMode = window.matchMedia
    && window.matchMedia('(prefers-color-scheme: dark)').matches;

Or maybe a more generic method:

1
2
3
4
5
6
7
8
9
const checkType = type => window.matchMedia
    && window.matchMedia(`(prefers-color-scheme: ${type})`).matches);

const mode = {
    is : {
        dark: checkType('dark'),
        light: checkType('light')
    }
};
1
2
mode.is.dark; // true
mode.is.light; // false

matchMedia(query) returns a new MediaQueryList object with the parsed results of the specified media query string.

Detecting the prefered color scheme in CSS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Light mode */
@media (prefers-color-scheme: light) {
    body {
        background-color: #000;
        color: white;
    }
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
    body {
        background-color: #000;
        color: white;
    }
}

Note for the spec:

User preferences can also vary by medium. For example, a user may prefer dark themes on a glowing screen, but light themes when printing (to save ink and/or because inked text on blank paper prints better than blank letterforms knocked out of an inked background). UAs are expected to take such variances into consideration so that prefers-color-scheme reflects preferences appropriate to the medium rather than preferences taken out of context.

Handling prefered color changes:

1
2
3
4
5
window.matchMedia('(prefers-color-scheme: dark)')
    .addListener((e) => {
        const isDarkMode = e.matches;
        console.log(`${isDarkMode ? '🌚' : '🌞'}.`);
    });

Force setting dark mode:

1
2
3
4
5
6
7
8
9
10
11
12
13
const forceDarkMode = () => [...document.styleSheets[0].rules].forEach(rule => {
     const mediaText = rule.media && rule.media.mediaText || [];
     const hasColorScheme = mediaText.includes("prefers-color-scheme");
     const hasLightScheme = hasColorScheme && mediaText.includes("light");

     // Remove light mode if.
     if (hasLightScheme) {
         rule.media.deleteMedium("(prefers-color-scheme: light)");
     }

     // Append Dark mdoe.
     rule.media && rule.media.appendMedium("(prefers-color-scheme: dark)");
 });

Comments