Engineering 4 min

How to add dark mode to your website

Written by Luis Serrano
Oct 16, 2019

Share

share to linkedInshare to Twittershare to Facebook
Link copied
to clipboard

Following the trend of dark mode, I thought this would be a good challenge to create my first library and help developers add dark mode themes to their websites.

At Remote, specially in our blog, we thought it would be nice to add dark mode and so we implemented an initial version. The problem was that our initial implementation didn’t fit all our future use cases and because we’ve updated the project in Gatsby to use the new version of react, our implementation became stale.

Instead of taking time to implement something specifically for Gatsby and worrying about SSR, we decided to find and use a library that would take care of that for us. If you want to know where we’re using our time at Remote, check https://remote.com/blog/solving-global-employment-through-remote 😛.

But to use this technique in all React-based websites and using the Context API that allows us to access the state easily in all components was not possible . That’s were I’ve found a good niche to contribute.

So I built a library based on the Context API and React hooks which allows you to easily implement dark mode.

https://github.com/luisgserrano/react-dark-mode

Continue reading for some examples.

Accessing state inside React components

As I said, this library uses the Context API so you should have at least React 16.3.0.

Changing the logo src based on the theme

To help you out with styling your app, we detect if the user has requested the system to use a light or dark color theme (by using the prefers-color-scheme CSS media feature) and set this theme as a class of the body tag like <body class="dark">.

By having this, you can create different styles when the body tag as the css class dark or light.

Since we’re using the Context API you should add our provider on top of your top level component so that all the child components have access to this state.

You can use the context in any child component of the <Provider> and this context exposes the mode variable, which is the theme that can be light or dark and the toggleMode function which toggles the theme. When the mode changes, this component will re-render.

javascript
1import Provider, { useDarkmodeContext } from 'react-use-dark-mode';
2
3// Images
4import BlackLogo from './blackLogo.svg';
5import WhiteLogo from './WhiteLogo.svg';
6
7const Header = () => {
8 const { mode, toggleMode } = useDarkmodeContext();
9
10 function getLogo(theme) {
11 return theme === "light" ? BlackLogo : WhiteLogo;
12 }
13
14 return (
15 <header>
16 <img src={getLogo(mode)} alt="Logo" />
17 <button type="button" onClick={toggleMode}>Toggle darkmode</button>
18 </header>
19 );
20};
21
22ReactDOM.render(
23 <Provider>
24 <Header />
25 </Provider>,
26 document.getElementById('header')
27);

Using CSS variables

css
1:root {
2 --textPrimaryColor: #000;
3 --backgroundPrimaryColor: #fff;
4}
5
6body {
7 color: var(--textPrimaryColor);
8 background-color: var(--backgroundPrimaryColor);
9}
10
11body.dark {
12 --textPrimaryColor: #fff;
13 --backgroundPrimaryColor: #000;
14}
15
16.block__element {
17 color: var(--textPrimaryColor);
18}

As you can see, you only need to add the CSS based on the theme and add a button to toggle the theme.

Conclusion

The benefit of this library is if you need to change something that you can’t with CSS and you’re using React, like in the example above where we had to change the src of an image based on the theme, you can now easily subscribe to the theme change and apply your custom behavior.

Overall, this has been an excellent experience to start in the world of open source, the feeling that someone is using your work and you’re helping someone building products with it is awesome.

Subscribe to receive the latest
Remote blog posts and updates in your inbox.