Skip to main content
Responsive Web Design
CHAPTER 17 Beginner

Dark Mode and Adaptive UI

Updated: May 12, 2026
20 min read

# Chapter 17: Dark Mode and Adaptive UI

1. Introduction

Welcome to Chapter 17! A responsive design doesn't just respond to the *size* of the screen; it responds to the *environment* of the user. With the rise of OS-level Dark Mode, users now expect websites to automatically switch to a dark theme at night to save battery life and reduce eye strain. Adapting to these preferences is a hallmark of premium web design.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Use the @media (prefers-color-scheme) query.
  • Implement CSS Custom Properties (Variables) to create theme toggles.
  • Design an accessible Dark Mode color palette.
  • Understand how to adapt images for dark environments.

3. Beginner-Friendly Explanations

Imagine walking into a movie theater.
  • If the theater lights are fully on, it's easy to read your ticket, but the movie screen looks washed out.
  • When the movie starts, the lights dim. The environment *adapts*. Now, the bright screen is easy to see, and your eyes relax.

Dark Mode is the theater dimming the lights. If a user is looking at their phone in bed at 2 AM, and your website blasts them with a massive, bright white background, it physically hurts their eyes. Adaptive UI prevents this.

4. Syntax Explanation

Just like we use @media (min-width: 768px) to detect screen size, we use a media query to detect the user's operating system (Windows, macOS, iOS, Android) theme preference.
css
12345678910111213
/* Default Light Theme */
body {
  background-color: white;
  color: black;
}

/* Detect if the user's phone/computer is in Dark Mode */
@media (prefers-color-scheme: dark) {
  body {
    background-color: #121212; /* Dark gray, not pure black */
    color: #e0e0e0;            /* Off-white */
  }
}

5. Real-World Examples

Look at GitHub:
  • During the day, the background is white, and the code text is dark.
  • At night (if your OS switches to dark mode), GitHub instantly changes to a dark gray background, and the code text flips to pastel colors for easy reading.

6. Multiple Code Examples

Example 1: The CSS Variable Strategy

Writing all your CSS twice (once for light, once for dark) is exhausting. Instead, use CSS Variables. Define the colors once at the root, and let the media query simply swap the variable values!
css
123456789101112131415161718192021222324
/* 1. Define variables for Light Mode */
:root {
  --bg-color: #ffffff;
  --text-color: #333333;
  --card-bg: #f9f9f9;
}

/* 2. Swap the variables for Dark Mode */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #121212;
    --text-color: #e0e0e0;
    --card-bg: #1e1e1e;
  }
}

/* 3. Apply the variables to your CSS! */
body {
  background-color: var(--bg-color);
  color: var(--text-color);
}
.card {
  background-color: var(--card-bg);
}

Example 2: Toning Down Images

Bright images can be jarring in dark mode. You can use CSS filters to subtly dim images when dark mode is active.
css
12345
@media (prefers-color-scheme: dark) {
  img {
    filter: brightness(.8) contrast(1.2); /* Dims the image slightly */
  }
}

Example 3: Adapting Shadows

Box shadows are built for light backgrounds (black shadow on white). In dark mode, a black shadow on a black background is invisible. Use lighter shadows or borders instead.
css
1234567891011
.card {
  box-shadow: 0 4px 6px rgba(0,0,0,0.1); /* Light mode shadow */
  border: 1px solid transparent;
}

@media (prefers-color-scheme: dark) {
  .card {
    box-shadow: none; /* Remove dark shadow */
    border: 1px solid #333; /* Add subtle border instead */
  }
}

7. Output Explanations

In Example 1, because the body and .card classes reference var(--bg-color), they don't actually care what the color is. When the operating system shifts to dark mode, the @media query overwrites the root variables, and the entire website repaints itself instantly without any JavaScript required!

8. Common Mistakes

  1. 1. Using Pure Black (#000000): Pure black causes smearing on OLED screens when scrolling and creates extreme contrast that causes eye fatigue. Use dark grays (e.g., #121212 or #1e293b).
  1. 2. Using Pure White (#FFFFFF) text on dark backgrounds: Pure white text on a dark background "vibrates" and is hard to read. Use off-white (e.g., #e2e8f0).
  1. 3. Ignoring saturation: A bright neon blue button looks great on white, but is blinding on dark gray. Desaturate your primary colors slightly for dark mode.

9. Best Practices

  • Plan your palette first: Before writing CSS, pick a background, surface (card), text, and primary brand color for *both* light and dark modes.
  • Use the color-scheme meta tag: Add <meta name="color-scheme" content="light dark"> to your HTML <head>. This tells the browser your site supports both, so it will automatically style default scrollbars and form inputs to match the OS theme!

10. Exercises

  1. 1. Write a basic HTML page with a white background and black text. Add the @media (prefers-color-scheme: dark) query to invert the colors. Go to your computer's OS settings, toggle "Dark Mode" on, and watch the webpage update live!
  1. 2. Create three CSS variables (--primary, --bg, --text) and apply them to a button. Swap the variables inside the dark mode media query.

11. Mini Project: Dark Mode Responsive Site

Build a simple article layout utilizing CSS variables that gracefully switches themes based on system preferences.
html
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
<!-- Responsive Design Example -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Tell browser we support both modes natively -->
    <meta name="color-scheme" content="light dark">
    <title>Adaptive Dark Mode</title>
    <style>
        /* LIGHT MODE VARIABLES (Default) */
        :root {
            --bg-page: #f8fafc;
            --bg-surface: #ffffff;
            --text-main: #0f172a;
            --text-muted: #64748b;
            --primary-color: #2563eb; /* Bright Blue */
            --border-color: #e2e8f0;
        }

        /* DARK MODE VARIABLES */
        @media (prefers-color-scheme: dark) {
            :root {
                --bg-page: #0f172a;      /* Dark slate */
                --bg-surface: #1e293b;   /* Slightly lighter slate for cards */
                --text-main: #f8fafc;    /* Off-white */
                --text-muted: #94a3b8;   /* Light gray */
                --primary-color: #60a5fa; /* Pastel Blue (desaturated) */
                --border-color: #334155;
            }
        }

        /* GLOBAL STYLES USING VARIABLES */
        body {
            background-color: var(--bg-page);
            color: var(--text-main);
            font-family: &#039;Segoe UI', system-ui, sans-serif;
            transition: background-color 0.3s, color 0.3s; /* Smooth fade when toggling */
            padding: 20px;
            display: flex;
            justify-content: center;
        }

        .article-card {
            background-color: var(--bg-surface);
            border: 1px solid var(--border-color);
            padding: 30px;
            border-radius: 12px;
            max-width: 600px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.05);
        }

        h1 { margin-top: 0; }
        
        p { color: var(--text-muted); line-height: 1.6; }

        .btn {
            display: inline-block;
            background-color: var(--primary-color);
            color: var(--bg-surface); /* Uses surface color for contrast */
            padding: 10px 20px;
            border-radius: 6px;
            text-decoration: none;
            font-weight: bold;
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <article class="article-card">
        <h1>The Magic of CSS Variables</h1>
        <p>By defining our color palette using CSS Custom Properties at the root level, we can instantly switch the entire look and feel of our website using a single media query. If you change your device to Dark Mode right now, this card will seamlessly update.</p>
        <a href="#" class="btn">Read Full Story</a>
    </article>
</body>
</html>

12. Coding Challenges

Challenge 1: Modify the Mini Project. When in Dark Mode, add a subtle box-shadow to the .article-card using a neon blue color (e.g., box-shadow: 0 0 15px rgba(96, 165, 250, 0.2);) to give it a cyberpunk "glow" effect.

13. MCQs with Answers

Q1: Which media query detects if the user wants a dark theme? A) @media (theme: dark) B) @media (prefers-color-scheme: dark) C) @media (background: black) D) @media (os-mode: night) *Answer: B*

Q2: Why should you avoid using #000000 (Pure Black) for dark mode backgrounds? A) It makes the website load slower. B) Pure black causes extreme contrast with white text leading to eye strain, and causes visual "smearing" on modern OLED screens. C) Browsers do not support pure black. D) It breaks CSS variables. *Answer: B*

14. Interview Questions

  1. 1. Explain the benefits of using CSS Custom Properties (Variables) for theming.
*Answer:* Without variables, you have to write two separate CSS declarations for every single element on your site (one for light, one for dark). With variables, you apply background: var(--bg) to your elements once. The media query simply changes the *value* of --bg at the root, and the entire site updates instantly.
  1. 2. What does <meta name="color-scheme" content="light dark"> do?
*Answer:* It opts the webpage into the browser's native dark mode support. This ensures that browser-controlled elements, like scrollbars, checkboxes, and select dropdowns, automatically render in a dark theme to match the rest of the page.

15. FAQs

Q: Can I build a button so the user can toggle dark mode manually? A: Yes! However, you will need JavaScript. You use JS to add a class like .dark-theme to the <body> when the button is clicked, and update your CSS variables inside that class instead of the media query.

16. Summary

Adaptive UI respects the user. By combining the prefers-color-scheme media query with CSS Variables, you can provide a stunning, eye-saving Dark Mode experience with minimal extra code. Always remember to use dark grays instead of pure black, and tone down your image brightness.

17. Next Chapter Recommendation

We know the techniques, but doing them efficiently without creating a mess of code is what separates juniors from seniors. Let's look at the overarching rules of the craft in Chapter 18: Responsive Web Design Best Practices.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·