Bird
Raised Fist0
Tailwindmarkup~15 mins

Dark mode toggle with JavaScript in Tailwind - Deep Dive

Choose your learning style10 modes available
Overview - Dark mode toggle with JavaScript
What is it?
Dark mode toggle with JavaScript is a way to let users switch a website's colors between light and dark themes. It uses JavaScript to change styles dynamically when a user clicks a button. Tailwind CSS helps by providing ready-made classes for both light and dark appearances. This makes websites easier on the eyes in different lighting conditions.
Why it matters
Without dark mode, users might find bright screens uncomfortable, especially at night or in low light. This can cause eye strain and reduce time spent on a website. Dark mode toggle improves user experience by giving control over appearance. It also shows modern design care, making websites feel up-to-date and user-friendly.
Where it fits
Before learning this, you should know basic HTML, CSS, and JavaScript. Understanding how Tailwind CSS classes work helps a lot. After this, you can explore advanced theming, accessibility improvements, and saving user preferences with local storage.
Mental Model
Core Idea
Dark mode toggle switches the website’s color theme by adding or removing a special class that changes styles instantly.
Think of it like...
It’s like flipping a light switch in a room to change from bright daylight to cozy evening lighting, making the space feel different but still the same room.
┌───────────────┐       ┌───────────────┐
│ User clicks   │──────▶│ JavaScript    │
│ toggle button │       │ toggles class │
└───────────────┘       └───────────────┘
          │                      │
          ▼                      ▼
┌──────────────────────────────┐
│ Tailwind CSS applies styles   │
│ based on presence of 'dark'  │
│ class on <html> or <body>    │
└──────────────────────────────┘
          │
          ▼
┌──────────────────────────────┐
│ Website colors switch to dark │
│ or light theme instantly     │
└──────────────────────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding Tailwind Dark Mode Basics
🤔
Concept: Learn how Tailwind CSS handles dark mode using a special class.
Tailwind uses a 'dark' class on the root element (usually ) to switch styles. For example, 'bg-white dark:bg-gray-900' means the background is white normally, but dark gray when 'dark' class is present. This lets you write both light and dark styles in one place.
Result
You see how adding or removing the 'dark' class changes colors automatically.
Understanding this class-based switch is key to controlling dark mode with JavaScript.
2
FoundationBasic JavaScript to Toggle Classes
🤔
Concept: Learn how to add or remove a CSS class on an element using JavaScript.
Using JavaScript, you can select the element and toggle the 'dark' class when a button is clicked. Example: const html = document.documentElement; const toggle = document.getElementById('toggle'); toggle.addEventListener('click', () => { html.classList.toggle('dark'); });
Result
Clicking the button adds or removes the 'dark' class on .
Knowing how to toggle classes dynamically lets you control styles without reloading the page.
3
IntermediateCreating a Dark Mode Toggle Button
🤔Before reading on: do you think the toggle button needs to be inside the or can it be anywhere? Commit to your answer.
Concept: Build a button in HTML that users click to switch themes.
Add a button with an id like 'toggle' inside your HTML body. Style it with Tailwind for visibility. Example:
Result
A visible button appears on the page that users can click.
Placing the button inside ensures it is visible and interactive for users.
4
IntermediateCombining Tailwind and JavaScript for Toggle
🤔Before reading on: do you think toggling the 'dark' class on affects all child elements styled with dark mode classes? Commit to your answer.
Concept: Connect the button click to toggling the 'dark' class on the root element to switch themes.
Use JavaScript to listen for the button click and toggle the 'dark' class on . Tailwind automatically applies dark styles to all elements with 'dark:' classes. This means the whole page changes theme instantly.
Result
Clicking the button switches the entire page between light and dark themes.
Toggling the root class cascades style changes everywhere, making theme switching efficient.
5
AdvancedPersisting User Preference with Local Storage
🤔Before reading on: do you think the dark mode setting stays after refreshing the page by default? Commit to your answer.
Concept: Save the user's theme choice in the browser so it stays after reloads.
Use localStorage to save the theme state: // On load if(localStorage.getItem('theme') === 'dark') { document.documentElement.classList.add('dark'); } // On toggle const button = document.getElementById('toggle'); button.addEventListener('click', () => { document.documentElement.classList.toggle('dark'); if(document.documentElement.classList.contains('dark')) { localStorage.setItem('theme', 'dark'); } else { localStorage.setItem('theme', 'light'); } });
Result
User's dark mode choice remains even after refreshing or reopening the page.
Remembering user preference improves experience and shows attention to detail.
6
ExpertHandling System Dark Mode Preference Automatically
🤔Before reading on: do you think JavaScript can detect if the user’s device prefers dark mode? Commit to your answer.
Concept: Use the CSS media query 'prefers-color-scheme' in JavaScript to detect system theme preference and set initial mode accordingly.
Check system preference on page load: const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; const storedTheme = localStorage.getItem('theme'); if(storedTheme === 'dark' || (!storedTheme && prefersDark)) { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); }
Result
The website respects the device’s dark mode setting by default, unless the user has chosen otherwise.
Respecting system preferences creates a seamless, user-friendly experience without extra clicks.
Under the Hood
Tailwind CSS generates two sets of styles: one for normal mode and one prefixed with 'dark:'. When the 'dark' class is added to the root element, CSS selectors with 'dark:' become active, overriding normal styles. JavaScript toggles this class dynamically, causing the browser to reapply styles instantly without reloading. Local storage stores the user's choice as a simple string, which JavaScript reads on page load to restore the theme. The 'prefers-color-scheme' media query lets JavaScript detect the user's system theme preference, enabling automatic theme setting.
Why designed this way?
Tailwind’s class-based dark mode was designed for simplicity and performance. Instead of complex CSS variables or multiple stylesheets, toggling a single class changes the theme globally. This avoids heavy JavaScript or page reloads. Local storage was chosen because it’s a simple, widely supported way to remember user settings without server calls. Detecting system preference respects user environment and reduces friction, improving adoption.
┌───────────────┐
│ User clicks   │
│ toggle button │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ JavaScript    │
│ toggles 'dark'│
│ class on <html>│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Tailwind CSS  │
│ applies dark  │
│ styles where  │
│ 'dark:' used  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Page colors   │
│ switch theme  │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does toggling the 'dark' class on a single element affect all elements styled with 'dark:' classes? Commit yes or no.
Common Belief:Toggling 'dark' on one element only changes that element’s style, not the whole page.
Tap to reveal reality
Reality:Because CSS selectors cascade, adding 'dark' to the root element affects all child elements with 'dark:' classes, changing the entire page theme.
Why it matters:If you toggle 'dark' on a child element, the rest of the page won’t change, causing inconsistent themes and confusing users.
Quick: Does the dark mode setting stay after refreshing the page without extra code? Commit yes or no.
Common Belief:Once toggled, the dark mode stays active even after page reload automatically.
Tap to reveal reality
Reality:Without saving the choice (e.g., in localStorage), the page resets to default styles on reload, losing the toggle state.
Why it matters:Users get frustrated if their preference resets every time, reducing trust and usability.
Quick: Can JavaScript detect the user’s system dark mode preference? Commit yes or no.
Common Belief:JavaScript cannot know if the user’s device prefers dark mode or not.
Tap to reveal reality
Reality:JavaScript can use the 'prefers-color-scheme' media query to detect system preference and set the theme accordingly.
Why it matters:Ignoring system preference forces users to manually toggle, reducing convenience and modern feel.
Quick: Is it best practice to use inline styles for dark mode toggling? Commit yes or no.
Common Belief:Using inline styles with JavaScript to change colors is simpler and better than toggling classes.
Tap to reveal reality
Reality:Toggling classes is more efficient, keeps styles centralized, and works better with Tailwind’s utility classes.
Why it matters:Inline styles can cause maintenance headaches, override CSS unintentionally, and reduce performance.
Expert Zone
1
Tailwind’s dark mode class can be configured to apply on 'class' or 'media' strategy, affecting how toggling works.
2
Toggling the 'dark' class on is preferred over because some browsers apply styles differently, and it ensures full coverage.
3
When stacking multiple toggles or themes, managing class order and specificity becomes critical to avoid style conflicts.
When NOT to use
Avoid using JavaScript toggles if your site is static and you want to rely solely on system preferences; instead, use Tailwind’s 'media' strategy. For complex theming beyond light/dark, consider CSS variables or CSS-in-JS solutions for more flexibility.
Production Patterns
In production, dark mode toggles often include animations for smooth transitions, accessibility features like ARIA labels, and sync with OS preferences. User preferences are saved in localStorage or cookies, and sometimes synced with user accounts for cross-device consistency.
Connections
CSS Variables (Custom Properties)
Alternative theming method
Knowing how CSS variables work helps understand more flexible theming beyond class toggling, enabling dynamic color changes without class switches.
User Experience Design
Improves usability and comfort
Understanding dark mode toggles connects to UX principles of user control and reducing eye strain, showing how technical features impact human feelings.
Electrical Light Switches
Physical analogy of toggling states
Recognizing toggling as switching states helps grasp how a single action can change an entire environment instantly.
Common Pitfalls
#1Not saving the user’s dark mode choice causes the theme to reset on page reload.
Wrong approach:button.addEventListener('click', () => { document.documentElement.classList.toggle('dark'); });
Correct approach:button.addEventListener('click', () => { document.documentElement.classList.toggle('dark'); if(document.documentElement.classList.contains('dark')) { localStorage.setItem('theme', 'dark'); } else { localStorage.setItem('theme', 'light'); } });
Root cause:Forgetting to persist state means the toggle only affects the current page view, not future visits.
#2Toggling the 'dark' class on a child element instead of the root element leads to partial theme changes.
Wrong approach:document.getElementById('someDiv').classList.toggle('dark');
Correct approach:document.documentElement.classList.toggle('dark');
Root cause:Misunderstanding CSS cascade and scope causes inconsistent styling.
#3Ignoring system dark mode preference forces users to manually toggle every time.
Wrong approach:Only toggle dark mode on button click without checking system preference on load.
Correct approach:On page load, check window.matchMedia('(prefers-color-scheme: dark)').matches and set theme accordingly.
Root cause:Not leveraging built-in browser features reduces user convenience.
Key Takeaways
Dark mode toggle works by adding or removing a 'dark' class on the root element, triggering Tailwind’s dark styles.
JavaScript toggles this class dynamically, letting users switch themes instantly without page reloads.
Saving the user’s choice in localStorage keeps the theme consistent across visits, improving experience.
Detecting system dark mode preference with 'prefers-color-scheme' lets the site respect user environment automatically.
Proper placement of the toggle and understanding CSS cascade ensures the entire page theme changes smoothly and consistently.

Practice

(1/5)
1. What does adding the dark class to the html element do in Tailwind CSS?
easy
A. It disables all CSS styles on the page.
B. It enables dark mode styles throughout the website.
C. It changes the font size to larger values.
D. It hides all images on the page.

Solution

  1. Step 1: Understand Tailwind dark mode mechanism

    Tailwind applies dark mode styles when the dark class is present on the html element.
  2. Step 2: Effect of the dark class

    Adding dark triggers alternate color schemes and styles designed for dark backgrounds.
  3. Final Answer:

    It enables dark mode styles throughout the website. -> Option B
  4. Quick Check:

    dark class = enables dark mode [OK]
Hint: Remember: dark class on html toggles dark mode styles [OK]
Common Mistakes:
  • Thinking dark class disables styles
  • Confusing dark class with font size changes
  • Assuming dark class hides images
2. Which JavaScript code correctly toggles the dark mode class on the html element when a button is clicked?
easy
A. document.documentElement.classList.toggle('dark');
B. document.body.classList.add('dark');
C. document.getElementById('dark').classList.remove('dark');
D. document.querySelector('html').style.dark = true;

Solution

  1. Step 1: Identify the root element for dark mode

    Dark mode toggles the dark class on the html element, accessible as document.documentElement.
  2. Step 2: Use correct method to toggle class

    The classList.toggle('dark') method adds or removes the class on each click.
  3. Final Answer:

    document.documentElement.classList.toggle('dark'); -> Option A
  4. Quick Check:

    Toggle dark class on html element = document.documentElement.classList.toggle('dark'); [OK]
Hint: Use document.documentElement.classList.toggle('dark') to toggle dark mode [OK]
Common Mistakes:
  • Using document.body instead of document.documentElement
  • Using add or remove instead of toggle
  • Trying to set style.dark property which doesn't exist
3. What will be the visible background color of this page after clicking the toggle button once?
<html class="dark">
  <body class="bg-white dark:bg-gray-900">
    <button id="toggle">Toggle Dark Mode</button>
  </body>
</html>

<script>
  document.getElementById('toggle').addEventListener('click', () => {
    document.documentElement.classList.toggle('dark');
  });
</script>
medium
A. Gray background (#1a202c)
B. No background color
C. Black background
D. White background

Solution

  1. Step 1: Initial state has dark class on html

    The page starts with dark class, so background is gray (#1a202c) from dark:bg-gray-900.
  2. Step 2: Clicking toggle removes dark class

    Toggle removes dark class, so bg-white applies, making background white.
  3. Final Answer:

    White background -> Option D
  4. Quick Check:

    Toggle removes dark class, background = white [OK]
Hint: Toggle flips dark class, switching background colors [OK]
Common Mistakes:
  • Assuming background stays gray after toggle
  • Confusing initial class presence
  • Ignoring that toggle removes dark class
4. This JavaScript code is meant to toggle dark mode but does not work. What is the error?
const btn = document.getElementById('toggle');
btn.onclick = function() {
  document.querySelector('html').classList.add('dark');
  document.querySelector('html').classList.remove('dark');
};
medium
A. The class name should be 'dark-mode', not 'dark'.
B. The selector 'html' is incorrect; should be 'body'.
C. It adds and removes 'dark' class immediately, so no visible change.
D. The event listener should be 'addEventListener', not 'onclick'.

Solution

  1. Step 1: Analyze the toggle logic

    The code adds then immediately removes the dark class on the same element in one function call.
  2. Step 2: Effect on the page

    Because add and remove happen instantly, the class never stays applied, so no dark mode effect is visible.
  3. Final Answer:

    It adds and removes 'dark' class immediately, so no visible change. -> Option C
  4. Quick Check:

    Immediate add and remove cancels out [OK]
Hint: Toggle class once; don't add and remove immediately [OK]
Common Mistakes:
  • Thinking 'onclick' is invalid
  • Using wrong selector for dark mode
  • Confusing class name with 'dark-mode'
5. You want to save the user's dark mode preference so it stays after page reload. Which JavaScript approach correctly implements this with Tailwind CSS?
1. On toggle, add/remove 'dark' class on <html>.
2. Save preference in localStorage.
3. On page load, read preference and set 'dark' class accordingly.

Which code snippet correctly sets dark mode on page load?
hard
A. if(localStorage.getItem('theme') === 'dark') { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); }
B. document.documentElement.classList.toggle(localStorage.getItem('theme'));
C. localStorage.setItem('theme', document.documentElement.classList.contains('dark'));
D. document.body.classList.add(localStorage.getItem('theme'));

Solution

  1. Step 1: Retrieve saved theme from localStorage

    Use localStorage.getItem('theme') to get saved preference.
  2. Step 2: Apply or remove 'dark' class based on preference

    If preference is 'dark', add dark class to html, else remove it.
  3. Final Answer:

    if(localStorage.getItem('theme') === 'dark') { document.documentElement.classList.add('dark'); } else { document.documentElement.classList.remove('dark'); } -> Option A
  4. Quick Check:

    Check saved theme and add/remove class accordingly [OK]
Hint: Check localStorage theme and add/remove 'dark' class on html [OK]
Common Mistakes:
  • Using toggle with localStorage value directly
  • Saving boolean instead of string in localStorage
  • Adding class to body instead of html
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard