Using CSS to honour visual preferences

At the beginning of October, I attended both ViewSource and Fronteers Conferences in Amsterdam (write up to come still). One of the many takeaways from those conferences was from a talk by Melanie Richards, a member of the Microsoft Edge platform team and participant of the W3C web standards communities, including the CSS Working Group. During her talk, she introduced some new CSS media queries to help websites honour peoples visual preferences.

Some of the media queries she covered are a little way out yet because the standards for them are still under discussion, but one that we can use now is:

@media ( prefers-color-scheme: value ) {}

This media query honours which theme you have chosen for your OS, light or dark, and will allow you to adjust a websites colour scheme accordingly. This means that with only a few additional lines of CSS, we can have a massive impact on a user’s visual experience of the sites we build.

Using prefers-color-scheme

@media ( prefers-color-scheme: value ) {} works, pretty much the same way as any other media query, but will only accept one of three values: no-preference | light | dark.

So, if we want to make some changes to our themes colour scheme that would only take effect if the operating system is using dark mode, we could set some custom properties like this:

:root {
    --bg-color: white;
    --color-brand: red; 
    --color-text: black;

    @media ( prefers-color-scheme: dark ) {
        --bg-color: black;
        --color-brand: yellow; 
        --color-text: white;

Our base CSS would then look like:

body {
    background-color: var( --bg-color );
    color: var( --color-text );

a {
    color: var( --color-brand );

When the operating system is set to light mode or it’s not specified, this example website would have a white background, black text and red links. But when changed to dark mode it would have a black background, white text and yellow links. Pretty neat right?

Using this technique we can do other things to help honour visual preferences as well, like reducing the brightness of images when in dark mode by applying filter:

@media ( prefers-color-scheme: dark ) {

If changing the brightness and contrast didn’t help enough, we could instead swap out the image and replace it with another one by using the media query within the <picture> element instead.

    <source srcset="image-dark.jpg" media="(prefers-color-scheme: dark)">
    <img src="image-light.jpg" alt="light image">

Something that is also extremely useful is using currentColor to control the colour of inline SVGs. If we had an SVG on our site that was wrapped in <a> tag, maybe a company logo, like this:

<a href="">
    <svg />

We could set the CSS for that SVG as:

svg {
    fill: currentColor;

instead of specifying a hex value for the fill.

currentColor works by inheriting the specified colour value of an outer container, if nothing is specified it will default to black. It gets used a lot on SVGs, but it can be used anywhere a colour value can be specified.

In this example, because a colour has been set for the <a> tag already using custom properties and the @media ( prefers-color-scheme: dark ) {} media query, we don’t need to write any extra lines of CSS to change the colour of the SVG depending on the light or dark mode. If we apply currentColor to any strokes or fills, the SVG will take on the colours of the surrounding <a> tag. Awesome 🙂

Hopefully, you all agree that this is already pretty powerful, as more new features get added to operating systems, more CSS will be introduced allowing us to tailor the visual experience to the user’s individual needs more and more.

And what I really like about it is, we don’t need to worry about browser compatibility either. If the browser does not support this media query then it will most probably be an older browser on an old operating system that doesn’t have the option to switch between light and dark mode anyway, so it will just be ignored. Awesome! 🎉

If you would like to have a look at the CodePen I used to experiment with this, it can be found here: View the pen and change your colour scheme in your operating systems to see the changes.