In this article we'll explore using the prefers-color-scheme
media feature through media queries in CSS and Javascript to act on the dark color scheme setting in the following segments:
- Prefers-color-scheme media feature in CSS
- Prefers-color-scheme media feature in Javascript
- Acting on preference changes in Javascript
Compatibility: While this function has wide support, it is still experimental and not supported on Opera, IE, and Edge (this might change when Edge changes render engine soon). Implementing this should be considered a nice to have feature, be careful not to let any other functionality depend on it.
Links to documentation: In the CSS examples the property names, and pseudo classes and elements link to their MDN web docs pages.
Prefers-color-scheme media feature in CSS
Media queries are very useful in CSS, it's what makes it possible to change styles depending on window size for example. Using media queries, we can also find out what color scheme preference a user has set.
Let's imagine the most basic style we can, only setting a color for text and background, and a color for our links.
Now, we can imagine our dark mode can be very simple too, by just switching these colors around. We can do that by putting it in a media query checking for prefers-color-scheme
. Prefers-color-scheme has 3 possible values:
- no-preference: user has no set preference
- light: user prefers a light color scheme
- dark: user prefers a dark color scheme
With these possibilities, we now know we want to apply our dark mode when the prefers-color-scheme
is "dark". It might look like this.
Within a media query block you can add all your CSS that applies to that rule. This works well, and won't break if the browser does not support it, defaulting to the original light colors and ignoring the media query.
A drawback of using only CSS is that it does not allow the user to switch back to your default style. Let's take a look at our options with JavaScript next.
Prefers-color-scheme media feature in Javascript
For Javascript, imagine we already implemented a toggle on our website that switches between a light and dark color scheme. For this we could have a .darkmode
class we toggle on our html
element using JavaScript, and our simple CSS might now look like this.
To toggle dark mode by default if a user has this preference, we will check the prefers-color-scheme
media feature using the window.matchMedia()
function in Javascript.
We will by using the matches
property to get a true or false value from our query. As you will see in the following example, the query is the same one we used in our CSS previously.
With this bit of JavaScript in your page the dark mode class will be added to, or removed from, your html
element when the JavaScript is run.
Acting on preference changes in Javascript
What about a user changing their preference while they're on your site? In CSS this will change will automatically apply, but in JavaScript we will have to make sure we keep an ear out by adding a listener.
What we'll do is wrap our check in a function, call that function so it will be run once when the page is opened, and add a listener to run the function when the preference changes.
With this function and listener in place, the class will automatically be added or removed when the JavaScript is run and whenever the preferred setting is changed.
Depending on how you toggle your dark mode, you might need to add a few lines of code to make sure your toggle correctly communicates the current setting.
Notes on accessibility
Aside from prefers-color-scheme
there are other media features you might want to consider using from an accessibility standpoint, such as prefers-contrast
and prefers-reduced-motion
so users that have set these preferences have a more pleasant and accessible experience on your website.