14

2020-03-23-honouring-colour-scheme-in-css

 5 years ago
source link: https://github.com/tamouse/swaac/blob/master/posts/2020/03/2020-03-23-honouring-colour-scheme-in-css.md
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
title date category tags

Honouring the user's preferred colour scheme in CSS

2020-03-23T03:32

css

colour-scheme

dark-mode

light-mode

How do I honour the user's chosen preferred colour scheme in the CSS I'm writing? Recently MacOS introduced dark mode in Mojave, and further added a shifting light and dark mode to match the time of day in Catalina. I'd like my sites, but more importantly, my React apps to follow this.

Background

The W3C has defined a media query, prefers-color-scheme ( Defined in Media Queries Level 5 Draft, March 2020 ). It has some implementations already. At least it's on the majors, so it's probably okay to use.

Media query

The check to see what colour scheme the user has set is done with a media query:

@media screen and (prefers-color-scheme: light) {
  /* settings for light scheme */
}
@media screen and (prefers-color-scheme: dark) {
  /* settings for dark scheme */
}

So this is clearly possible in regular CSS.

Using in styled-components

Since I most often code in React, and most often use styled-components library to implement CSS-in-JS, I need a way that this will work. Turns out it's not so bad, using SC's ThemeProvider .

In your theme file, set up the various colours, with a group for light mode and another group for dark mode:

const colors = {
    light: {
        primaryText: "#333",
        primaryBg: "#FFF",
        // and so on
    },
    dark: {
        primaryText: "#F2F2F2",
        primaryBg: "#000",
        // and so on
    },
    common: {
        // colors that work for both
    }
};

export default {
    colors
};

Where I wrap react components with the SC ThemeProvider, I can import and provide the theme as usual:

import React from "react";
import { ThemeProvider} from 'styled-components';
import theme from "../../theme";

function App({ children }) {
    return (
        <ThemeProvider theme={theme} >
          {children}
        </ThemeProvider>
    );
}

export default App;

Then later, in the styled compeonent, this happens:

import styled from 'styled-components';

export const SomeSection = styled.section`
  color: ${props => props.theme.colors.light.primaryText};
  backgound-color: ${props => props.theme.colors.light.primaryBg};

  @media screen and (prefers-color-scheme: light) {
    color: ${props => props.theme.colors.light.primaryText};
    backgound-color: ${props => props.theme.colors.light.primaryBg};
  }
  @media screen and (prefers-color-scheme: dark) {
    color: ${props => props.theme.colors.dark.primaryText};
    backgound-color: ${props => props.theme.colors.dark.primaryBg};
  }
`

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK