How to create Dark Mode using only CSS
Tags: css, design, tutorial, webdev
Published: 2022-03-03 22:32:55

Dark Mode and dark interfaces are not a new thing as they have been a trend for many years. When Apple released a dark mode option with the iOS 13 update back in 2019, the trend took off.

**Using modern CSS, you can create dark mode with a few lines of code.**

Let's dive in!

#### 📚 Content

* [Dark mode is more than a trend](#dark-mode-is-more-than-a-trend)
* [Dark mode is accessibility](#dark-mode-is-accessibility)
* [How to set up dark mode with CSS](#how-to-set-up-dark-mode-with-css)
  * Create CSS Custom Properties (variables)
  * Create conditional styling
  * Apply styles
* [Demo and final code](#demo-and-final-code)

#### ✨ Bonus Content
* [Color-scheme meta tag and CSS property](#colorscheme-meta-tag-and-css-property)
* [How to test your code](#how-to-test-your-code)
  * Google Chrome Dev Tools
  * Device OS Settings

---

## TL;DR;

You can create dark mode using only **CSS Custom Properties aka CSS variables** and **CSS media feature `prefers-color-scheme`**:

```css
/* 1. Create global variables for text and background color */
:root {
  --color-text: black;
  --color-background: white;
}

/* 2. Add conditional styling for dark mode preference */
@media (prefers-color-scheme: dark) {
  /* Re-assign previous variables */
  :root {
    --color-text: white; /* black => white */
    --color-background: black; /* white => black */
  }
}

/* 3. Assign variables to page color and background */
body {
  color: var(--color-text);
  background-color: var(--color-background);
}
```

That's it 🔥 View my **CSS Only Dark Mode** [Codepen](https://codepen.io/laurilllll/pen/yLPKojZ).

---

## Dark mode is more than a trend

Dark mode is not a design trend. Dark interfaces can be easier on the eyes and reduce eye strain and fatigue. They can actually help reduce the sensation of discomfort felt when staring at websites with light backgrounds.

Dark mode also saves your device's battery life. It can reduce battery usage, especially on mobile devices.

---

## Dark mode is accessibility

Dark mode is also an accessibility (a11y) feature. **It's about respecting your users and their preferences so they can use your website the way they like.**

Besides responsive media queries, modern CSS has many cool media features and `prefers-color-scheme` is one of them.  [Quote from MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) 👇

> The prefers-color-scheme CSS media feature is used to detect if the user has requested a light or dark color theme. The user might indicate this preference through an operating system setting (e.g. light or dark mode) or a user agent setting.

Users can choose if they prefer light or dark mode from their operating system settings.

![Picture from macOS general settings.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4llkxl3oc2oi1ju3mx4.png)

(macOS)

![Picture from iOS Display & Brightness settings.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zf9qaupb806yxk67fobl.png)

(iOS)

With CSS, you can serve the user the theme they prefer. Media queries are used to conditionally apply styles. Media feature `prefers-color-scheme` is a **Media Query**, so you write it like you'd write your breakpoints:

```css
/* Breakpoint */
@media (min-width: 800px) {
  /* Add conditional styles here */
}

/* Prefers Color Scheme */
/* Dark */
@media (prefers-color-scheme: dark) {
  /* Add conditional styles here */
}
/* Light */
@media (prefers-color-scheme: light) {
  /* Add conditional styles here */
}
```

---

## How to set up dark mode with CSS

#### Create CSS Custom Properties (variables)

To setup color styles, I recommend using **variables** to keep your code DRY (don't repeat yourself). If you aren't familiar with CSS variables, you can read about them from [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/--*).

For the sake of this tutorial we keep things simple and use black and white as our colors. And we only style our text color and background color.

```css
/* 1. Create global variables for text and background color */
:root {
  --color-text: black;
  --color-background: white;
}
```

#### Create conditional styling

Next, let's apply **conditional styling for users who prefer dark mode**. By using a media query, we re-assign previous variables with new inverted values.

```css
/* 2. Add conditional styling for dark mode preference */
@media (prefers-color-scheme: dark) {
  /* Re-assign previous variables */
  :root {
    --color-text: white; /* black => white */
    --color-background: black; /* white => black */
  }
}
```

#### Apply styles

And finally, we **apply the variables** to our design:

```css
/* 3. Assign variables to page color and background */
body {
  color: var(--color-text);
  background-color: var(--color-background);
}
```

## Demo and final code

See the final effect in action of user changing between light and dark mode in OS settings: 

![GIF animation of user changing between light and dark mode in OS settings.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zd6aqe9w1bidmjnu44ui.gif)

👇 The final code in full.

```css
/* 1. Create global variables for text and background color */
:root {
  --color-text: black;
  --color-background: white;
}

/* 2. Add conditional styling for dark mode preference */
@media (prefers-color-scheme: dark) {
  /* Re-assign previous variables */
  :root {
    --color-text: white; /* black => white */
    --color-background: black; /* white => black */
  }
}

/* 3. Assign variables to page color and background */
body {
  color: var(--color-text);
  background-color: var(--color-background);
}
```

You can view the code and play with it in my [Codepen](https://codepen.io/laurilllll/pen/yLPKojZ).

---

## ✨ Bonus Content

### Color-scheme meta tag and CSS property

The `color-scheme` meta tag and CSS property takes care of two important things for you. This next quote is from [Google Developers web.dev](https://web.dev/color-scheme/) and I've taken the liberty to highlight some parts of it 👇

> They both make your life as a developer easier by allowing you to **opt your page in to theme-specific defaults of the user agent stylesheet**, such as, for example, form controls, scroll bars, as well as CSS system colors. At the same time, this feature **prevents browsers from applying any transformations on their own.**

By the order of values, you can determine the default appearance. Here's the syntax for both CSS and the corresponding HTML meta tag:

```css
:root {
  color-scheme: dark light;
}
```

(In the CSS example, the page author prefers **dark** theme.)

```html
<head>
  <meta name="color-scheme" content="light dark">
</head>
```

(In the HTML example, the page author prefers **light** theme.)

It is recommended to specify the `color-scheme` via the meta tag, so the browser can adopt to the preferred scheme faster.

---

### How to test your code

**Google Chrome Dev Tools**

You can test your code with Google Chrome Dev Tools.

1. Open up your Dev Tools Inspection panel by pressing `Command+Option+C` (Mac) or `Control+Shift+C` (Windows, Linux, Chrome OS).
1. Click on the **three dots** in the **upper right corner** => select **More tools** => click **Rendering**.
1. From the Rendering tab you can find the emulation for `prefers-colors-scheme`.

See the screenshots below 👇

![Image of Google Chrome Dev Tools' Rendering tab highlighting prefers-color-scheme emulation.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xp5k9l4zqn2i3ujfqrc7.png)

![Image of Google Chrome Dev Tools' Rendering tab prefers-color-scheme emulation turned to emulate dark mode.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hilrpchexfd3yantizcc.png)

**Device OS settings**

As shown before, you can change the appearance from you device settings. Screenshots are from macOS and iOS. You can find the same settings from Android and Windows devices.

![Picture from macOS general settings.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4llkxl3oc2oi1ju3mx4.png)

![Picture from iOS Display & Brightness settings.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zf9qaupb806yxk67fobl.png)

---

## Resources and further reading

* CSS Only Dark Mode [Codepen](https://codepen.io/laurilllll/pen/yLPKojZ) by me
* Color-scheme meta tag and CSS property at [web.dev](https://web.dev/color-scheme/)
* CSS Media Feature `prefers-color-scheme` at [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme)
* CSS Custom Properties aka CSS Variables at [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/--*)

---

## Thank you 🙏

I hope you found this article helpful 🔥

You can [follow me on Twitter](https://twitter.com/laurilllll) for more **CSS**, **Design System** and **Figma** content 💪