prefers-color-scheme: CSS Media Query
One device and app feature I've come to appreciate is the ability to change between light and dark modes. If you've ever done late night coding or reading, you know how amazing a dark theme can be for preventing eye strain and the headaches that result. macOS recently implemented a native dark mode but that mode doesn't convert websites to a dark interface, so you're still getting a bright site regardless of native theme. Wouldn't it be amazing if websites would also go dark or light based on user's system preference?
The CSS working group agrees, which is why they'vecreated aprefers-color-scheme
media query; a media query that signals what the user's theme preference is and allows you to code your site to match that preference!
Theprefers-color-scheme
media query has two effective values you can specify:light
anddark
:
/* Light mode */@media (prefers-color-scheme: light) { html { background: white; color: black; }}/* Dark mode */@media (prefers-color-scheme: dark) { html { background: black; color: white; }}
Coupled with your default site design, you could potentially offer three different designs: default (no-preference
), light modifications, and dark modifications.
To make managing colors in each mode easier, you can simply modify CSS variables within the media query:
/* Defaults */:root { --color-scheme-background: pink; --color-scheme-text-color: red;}/* Light mode */@media (prefers-color-scheme: light) { :root { --color-scheme-background: white; --color-scheme-text-color: black; }}/* Dark mode */@media (prefers-color-scheme: dark) { :root { --color-scheme-background: black; --color-scheme-text-color: white; }}/* Usage */html { background: var(--color-scheme-background); color: var(--color-scheme-text-color);}
If you want to use JavaScript to know which mode your user prefers, you can easily do so bygetting a CSS variable value:
html { content: ""; /* (ab)using the content property */}/* Light mode */@media (prefers-color-scheme: light) { html { content: "light"; /* (ab)using the content property */ }}/* Dark mode */@media (prefers-color-scheme: dark) { html { content: "dark"; /* (ab)using the content property */ }}
const mode = getComputedStyle(document.documentElement).getPropertyValue('content');// mode: "dark"
I'm pleased that there's an official media query for color/theme preference. As someone who suffers from minor headaches to skull numbing migraines, my preference is always a dark theme and I appreciate apps that put in the extra effort to provide me a painless user experience. We already use media queries to accommodate print and different viewport sizes, so let's take an extra step in providing colors based on user preference!
Note: At the time of posting, only Safari Preview 68 has implemented this media query. FollowBugzilla bug 1494034 to know Firefox's support status.
Recent Features
Write Simple, Elegant and Maintainable Media Queries with Sass
I spent a few months experimenting withdifferent approaches for writing simple, elegant and maintainable media queries with Sass. Each solution had something that I really liked, but I couldn't find one that covered everything I needed to do, so I ventured into creating my...
Serving Fonts from CDN
For maximum performance, we all know we must put our assets on CDN (another domain). Along with those assets are custom web fonts. Unfortunately custom web fonts via CDN (or any cross-domain font request) don't work in Firefox or Internet Explorer (correctly so, by spec) though...
Incredible Demos
Submit Button Enabling
"Enabling" you ask? Yes. We all know how to disable the submit upon form submission and the reasons for doing so, but what about re-enabling the submit button after an allotted amount of time. After all, what if the user presses the "stop"...
jQuery Comment Preview
I released aMooTools comment preview script yesterday and got numerous requests for a jQuery version. Ask and you shall receive! I'll use the exact same CSS and HTML as yesterday.The XHTMLThe CSSThe jQuery JavaScriptOn the keypress and blur events, we validate and...
Does
window.matchMedia()
not work for this?Yes,
matchMedia
does work. So that would be better than using computed style.Just added:
https://caniuse.com/#feat=prefers-color-scheme