Use “prefers-color-scheme” to detect macOS dark mode with CSS and Javascript

Since the introduction in MacOS Mojave “Dark Mode” has made its way to the mainstream.

If a user chooses to use “Dark Mode” the overall experience of the OS adapts to provide a consistent user experience.

Many companies introduced a dark theme for their apps in 2018. Spark, Things 3, Sketch or Ulysses to name a few.

There is a website that has a comprehensive list of many more apps and websites.

In this post, I’m going to explain how and why you should consider making a dark theme for your website too.

October 2019 — Update: Rowland I. Ekemezie has a great article related to “Dark Mode” with the focus on Sass.

Dark Mode for the Web

There are reasons why a person might prefer a dark theme over a light one.

  • It reduces stress on the eyes when reading in a dark environment.
  • Dark mode is enjoyable to look at.
  • It can save battery when using an OLED screen.
  • Better contrast.
  • Less Blue Light which supports a better sleep

Developers should build software that respects a user's decision for a certain user experience.

The problem is that there is currently no available cross-browser API to tell if a user has “Dark Mode” enabled. While many websites offer a dark version, it mostly comes down to a “per-website” setting that you have to activate.

Youtube Dark Mode
Ars Technica Dark Mode
CoinMarketCap Dark Mode

The CSS Working Group already has a draft to bring a native API for user preferences to the browser.

As of today, only Safari Technology Preview (Release 73) supports `prefers-color-scheme` Media Query. It is part of Media Queries Level 5 which you can read more about here

October 2019 — Update: Safari `Version 13.0.2` and Chrome 77 supports `prefers-color-scheme` to the best of my knowledge.

How to make use of `prefers-color-scheme` today

Chances are that your users don’t use Safari Technology Preview so you can either wait for the implementation to hit all major browsers or find a different solution.

October 2019 — Update: I decided to go in a different direction with my personal site and it no longer has an optional dark mode. It’s always dark.

For my personal website, I choose to respect the user’s system preference while providing a sensible default.

If you happen to visit my website during night time, you see the dark version, during the day the light version, however, if you use a supported browser it uses the system preference.

My website uses CSS Custom Properties to make the color scheme easily changeable via javascript. Be aware of the browser support! If you have to support older browsers you can use a polyfill.

Next is the `window.matchMedia` API. It supports testing media queries programmatically using JavaScript. There is also a polyfill available for older browsers.

You can also choose a more straightforward approach and use CSS only.


Adding a Dark mode to your website improves the user experience and doesn’t require much effort when you use CSS variables. As soon as `prefers-color-scheme` support lands in major browsers, users can experience your website in their preferred color scheme, and you will see a surge of “Dark Mode” enabled websites all over the internet.

You can check out the source code of my website on Github.

Thanks for reading.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store