How to Add a Dark Theme with Only CSS

2024-10-21

How to Add a Dark Theme with Only CSS

In this blog post, we'll learn how to add a dark theme to your website using only CSS. This method leverages the CSS prefers-color-scheme media query to automatically apply a dark or light theme based on the user's system settings.

By the end of this tutorial, you'll have a responsive dark theme for your site that switches based on user preference—without any JavaScript!

Step 1: Define CSS Variables for Themes

First, we'll use CSS variables to define the colors for both the light and dark themes. This allows us to switch between themes easily and consistently across your site.

In your main CSS file (e.g., globals.css), define the default (light) theme using :root:

:root {
  --background-color: #ffffff;
  --text-color: #000000;
  --link-color: #0070f3;
  --border-color: #eaeaea;
  --card-background-color: #fafafa;
  --code-background-color: #f5f5f5;
}

These variables will be used for elements like background color, text color, links, borders, and cards. By defining these variables in :root, they'll be applied globally across your site.

Step 2: Define the Dark Theme with prefers-color-scheme

Now, we want to create a dark theme that is applied when the user has their system set to dark mode. To do this, we’ll use the prefers-color-scheme: dark media query.

Below the light theme definition, add the dark theme like this:

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: #121212;
    --text-color: #e0e0e0;
    --link-color: #64b5f6;
    --border-color: #333;
    --card-background-color: #1e1e1e;
    --code-background-color: #2d2d2d;
  }
}

This will automatically apply the dark theme whenever the user's system preference is set to dark mode.

Step 3: Apply the Theme to Your Website

Now that we’ve defined our color variables, we can use them to style the elements on our website. For example, let’s apply the background color and text color to the body:

body {
  background-color: var(--background-color);
  color: var(--text-color);
  transition: background-color 0.3s, color 0.3s;
}

The transition property ensures a smooth transition between the light and dark themes.

You can apply the same approach to other elements like buttons, links, and cards. Here’s an example of how to style links and buttons:

a {
  color: var(--link-color);
}

button {
  background-color: var(--card-background-color);
  color: var(--text-color);
  border: 1px solid var(--border-color);
  padding: 10px;
  border-radius: 5px;
  cursor: pointer;
}

This will ensure that your buttons and links adapt to both themes without any additional work.

Step 4: Test the Dark Theme

Once you've defined your themes and applied them to the appropriate elements, it’s time to test the dark mode.

To test it:

  1. Switch your operating system to dark mode. On macOS, this can be done in System Preferences -> General -> Appearance. On Windows, go to Settings -> Personalization -> Colors and select Dark.
  2. Refresh your website and see the dark theme in action!

Your site should automatically switch to the dark theme when your system is in dark mode, thanks to the prefers-color-scheme media query.

Step 5: Optional - Light/Dark Theme Toggle (Without JavaScript)

While this method automatically applies the user’s system preference, you can also allow the user to toggle between light and dark themes manually.

However, to handle this fully client-side, you would typically need JavaScript to switch the theme manually. For now, we’re focusing on a solution that only uses CSS, so we’ll rely on the system preference.

Conclusion

By using only CSS and the prefers-color-scheme media query, we can provide a seamless dark theme experience for users who prefer it. This method is efficient and avoids the need for JavaScript.

Just by defining variables and applying media queries, your site can automatically switch between light and dark modes based on the user's system settings.

No need to worry about writing custom JavaScript, as CSS handles everything! Now, enjoy your clean, responsive dark theme!