Interactive Technical Demo

Building Dark Mode

Watch the code change in real-time as you toggle themes. Learn the technical implementation behind modern dark mode systems.

3 Methods
0 Lines Changed
0 Toggles
theme.css
:root {
  --bg: #ffffff;
  --text: #1a1a2e;
}
01

CSS Custom Properties

The modern approach using CSS variables that cascade through the DOM

variables.css Live
/* Define theme variables */
:root {
  --background: #ffffff;
  --foreground: #1a1a2e;
  --primary: #6366f1;
  --card: #f8fafc;
  --border: #e2e8f0;
}

/* Dark mode override */
[data-theme="dark"] {
  --background: #0f0f1a;
  --foreground: #f1f5f9;
  --primary: #818cf8;
  --card: #1e1e2e;
  --border: #2e2e3e;
}

/* Apply variables */
body {
  background: var(--background);
  color: var(--foreground);
}
theme.js Live
// Toggle theme attribute
function toggleTheme() {
  const html = document.documentElement;
  const current = html.getAttribute('data-theme');

  const next = current === 'dark'
    ? 'light'
    : 'dark';

  html.setAttribute('data-theme', next);

  // Persist preference
  localStorage.setItem('theme', next);
}

// Current state:
document.documentElement
  .getAttribute('data-theme')
// Returns: "light"
Live Preview

Card Component

This card responds to CSS variable changes in real-time.

Text automatically adapts to the theme using var(--foreground)

How it works:

  1. 1 Define color tokens as CSS custom properties on :root
  2. 2 Override values using attribute selectors like [data-theme="dark"]
  3. 3 Toggle the attribute with JavaScript to instantly cascade changes
02

Class Toggle Method

Traditional approach using class names to switch between themes

theme.css Live
/* Light theme (default) */
body {
  background-color: #ffffff;
  color: #1a1a2e;
}

/* Dark theme class */
body.dark-mode {
  background-color: #0f0f1a;
  color: #f1f5f9;
}

.card {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
}

body.dark-mode .card {
  background: #1e1e2e;
  border-color: #2e2e3e;
}
toggle.js Live
// Toggle dark mode class
const body = document.body;

function toggleDarkMode() {
  body.classList.toggle('dark-mode');

  const isDark = body.classList
    .contains('dark-mode');

  localStorage.setItem(
    'darkMode',
    isDark
  );
}

// Current class list:
body.classList.toString()
// Returns: ""
index.html Live
<body class="">
  <div class="card">
    <h3>Card Title</h3>
    <p>Content here</p>
  </div>
</body>

<!-- DOM Inspector -->
<!-- body element: -->
<body class="">
Live Preview

User Profile

The .dark-mode class cascades to all child elements.

How it works:

  1. 1 Define default light theme styles on base selectors
  2. 2 Create .dark-mode class with override styles
  3. 3 Use classList.toggle() to add/remove the class
03

System Preference Detection

Automatically match the user's OS theme preference using media queries

Detecting...
auto-theme.css System
/* Default light theme */
:root {
  --bg: #ffffff;
  --text: #1a1a2e;
}

/* Auto-detect dark preference */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f0f1a;
    --text: #f1f5f9;
  }
}

/* Media query status: */
/* prefers-color-scheme: light */
detect.js System
// Check system preference
const query = window.matchMedia(
  '(prefers-color-scheme: dark)'
);

const isDark = query.matches;
// Currently: false

// Listen for changes
query.addEventListener('change', (e) => {
  console.log(
    'Theme changed:',
    e.matches ? 'dark' : 'light'
  );
});

// Query object:
{
  media: "(prefers-color-scheme: dark)",
  matches: false
}
System Detection
Your OS Preference Light Mode
i

Change your system theme settings to see this update automatically!

How it works:

  1. 1 CSS media query prefers-color-scheme detects OS setting
  2. 2 JavaScript matchMedia() provides programmatic access
  3. 3 Event listener responds to real-time OS theme changes

Live DOM Inspector

Real-time view of the document's current state

document.documentElement <html data-theme="light">
document.body.classList DOMTokenList []
getComputedStyle --background #ffffff
getComputedStyle --foreground #1a1a2e
localStorage.theme "light"

Implementation Comparison

Feature
CSS Variables
Class Toggle
System Pref
Browser Support
95%+
99%+
93%+
Performance
Excellent
Good
Excellent
Dynamic Updates
Yes
Yes
Auto
User Control
Manual
Manual
OS Only
Specificity Issues
None
Some
None

About This Project

This technical demonstration showcases the dark mode feature I developed during my internship with Unadat, a financial wellness portal. Working remotely throughout the pandemic, I collaborated closely with the CEO to lead the development of a comprehensive theming system.

The Experience

Through user research and A/B testing, I validated design decisions that resulted in measurable improvements in user satisfaction and engagement. I worked with design and development teams to refine the interface, streamline navigation, and ensure visual consistency while implementing responsive design principles.

Key Contributions

  • Led dark mode development with customizable color schemes
  • Conducted user research and A/B testing to validate decisions
  • Optimized mobile UX with responsive design improvements
  • Implemented smooth theme transitions and persistent preferences
  • Collaborated on feature specifications and sprint planning

Design Principles

  • Progressive Enhancement: Core functionality works without JS
  • Mobile-First: Fully responsive with touch-optimized controls
  • Accessibility: Keyboard navigation and ARIA labels
  • Performance: Optimized animations and efficient DOM updates
CSS Custom Properties JavaScript ES6+ LocalStorage API Media Queries DOM Manipulation CSS Grid & Flexbox Keyframe Animations