Vue 3 TypeScriptVue Development and Vuejs DeveloperVue.js Tutorial

How to implement dark light mode in Vue 3 with Typescript CSS

Here's an illustration of a dark/light mode toggle switch for a website, showing a sliding switch with sun and moon icons on each side, suitable for various web designs.
To implement a dark/light mode toggle in Vue 3 with TypeScript and CSS, you can follow these steps. This approach will use Vue’s reactive properties, TypeScript support, and CSS classes for styling.

Steps to Implement Dark/Light Mode

  1. Set Up a Global Dark Mode State: Use Vue’s reactive to store the mode state.
  2. Toggle Dark Mode: Use a method to toggle between dark and light modes.
  3. Apply Dark Mode Styling: Use conditional CSS classes to apply dark mode styles.
  4. Persist the Mode: Optionally, save the mode in localStorage so it persists across page reloads.

Implementation

Here’s the complete setup:

Step 1: Define the Dark Mode State in a Composable

You can create a composable for managing the dark mode state.

typescriptCopy code// composables/useDarkMode.ts
import { ref, watchEffect } from 'vue';
const darkMode = ref<boolean>(false);
export function useDarkMode() {
  // Load dark mode preference from localStorage (optional)
  darkMode.value = localStorage.getItem('darkMode') === 'true';
  const toggleDarkMode = () => {
    darkMode.value = !darkMode.value;
    localStorage.setItem('darkMode', darkMode.value.toString());
  };
  // Watch for changes in darkMode and update the document body class
  watchEffect(() => {
    if (darkMode.value) {
      document.body.classList.add('dark-mode');
    } else {
      document.body.classList.remove('dark-mode');
    }
  });
  return { darkMode, toggleDarkMode };
}

Step 2: Create a Dark/Light Mode Toggle Component

Create a button to toggle the mode in a component.

vueCopy code<!-- components/DarkModeToggle.vue -->
<template>
  <button @click="toggleDarkMode">
    {{ darkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode' }}
  </button>
</template>
<script lang="ts" setup>
import { useDarkMode } from '../composables/useDarkMode';
const { darkMode, toggleDarkMode } = useDarkMode();
</script>
<style scoped>
button {
  cursor: pointer;
  padding: 0.5rem 1rem;
  font-size: 1rem;
}
</style>

Step 3: Add Dark Mode Styles in CSS

Define dark and light mode styles using CSS. You can apply a global class, such as dark-mode, to control theme styling.

cssCopy code/* styles.css (or any global CSS file) */
body {
  --background-color: #ffffff;
  --text-color: #000000;
  background-color: var(--background-color);
  color: var(--text-color);
}
body.dark-mode {
  --background-color: #121212;
  --text-color: #ffffff;
}

Step 4: Integrate in Your App Component

Use the toggle component in your app and add the CSS to your main file.

vueCopy code<!-- App.vue -->
<template>
  <div>
    <DarkModeToggle />
    <p>This is a sample text to demonstrate dark mode.</p>
  </div>
</template>
<script lang="ts" setup>
import DarkModeToggle from './components/DarkModeToggle.vue';
</script>
<style src="./styles.css"></style>

Step 5: Import Global Styles

Ensure that styles.css is imported in your main.ts or App.vue so that the dark mode styles are applied globally.

typescriptCopy code// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import './styles.css'; // Import the global styles
createApp(App).mount('#app');

Explanation of Key Parts

  • Composable (useDarkMode): Manages dark mode state and syncs it with localStorage.
  • Toggle Component (DarkModeToggle.vue): Renders a button to toggle dark mode.
  • CSS Variables: Define colors as variables, making it easy to switch between light and dark mode by changing the values.
  • Global CSS Class (.dark-mode): Applied to the <body> when dark mode is enabled, allowing global theming across the app.

Optional: Advanced – System Preference Detection

To detect the system’s preferred color scheme and apply it on initial load, add this to your useDarkMode composable:

typescriptCopy code// Set initial state based on system preference if no localStorage value exists
if (localStorage.getItem('darkMode') === null) {
  darkMode.value = window.matchMedia('(prefers-color-scheme: dark)').matches;
}

This setup provides a responsive dark/light mode implementation that persists across sessions and is easily managed across your Vue 3 app.

To implement a dark/light mode toggle in Vue 3 with TypeScript and CSS, we can follow these steps:

  1. Define a global theme state (either using ref or a computed property).
  2. Set up CSS variables to define the color schemes for dark and light modes.
  3. Apply classes on the main App.vue element to switch between dark and light themes.
  4. Persist the user’s preference using localStorage (optional).

Here’s a step-by-step implementation:

Step 1: Set Up the Theme State

Define a reactive state to toggle between dark and light themes. This can be done in a store (like with pinia or vuex), or directly within your App.vue.

typescriptCopy code// src/composables/useTheme.ts
import { ref, onMounted } from 'vue';
export function useTheme() {
  const theme = ref<'light' | 'dark'>('light');
  const toggleTheme = () => {
    theme.value = theme.value === 'light' ? 'dark' : 'light';
    document.documentElement.className = theme.value;
    localStorage.setItem('theme', theme.value);
  };
  onMounted(() => {
    const savedTheme = localStorage.getItem('theme') as 'light' | 'dark' | null;
    if (savedTheme) {
      theme.value = savedTheme;
      document.documentElement.className = savedTheme;
    }
  });
  return { theme, toggleTheme };
}

Step 2: Apply CSS Variables for Themes

Define CSS variables for dark and light modes in your CSS. This example shows how to do it in App.vue with scoped styles.

cssCopy code/* src/App.css */
:root {
  --bg-color: #ffffff;
  --text-color: #000000;
}
.dark {
  --bg-color: #1e1e1e;
  --text-color: #ffffff;
}
body {
  background-color: var(--bg-color);
  color: var(--text-color);
}

These variables allow you to change styles dynamically based on the theme class (.dark or .light) on the <html> or <body> element.

Step 3: Create a Toggle Button in Your Component

In App.vue, add a button to toggle between dark and light modes.

htmlCopy code<!-- src/App.vue -->
<template>
  <div>
    <button @click="toggleTheme">Toggle Theme</button>
    <p>Current theme: {{ theme }}</p>
    <!-- Other components and content here -->
  </div>
</template>
<script lang="ts" setup>
import { useTheme } from './composables/useTheme';
const { theme, toggleTheme } = useTheme();
</script>
<style scoped>
@import './App.css';
</style>

Step 4: Use the CSS Variables in Other Components

When styling components, you can now use the CSS variables, and they’ll automatically adjust based on the selected theme.

For example:

htmlCopy code<!-- src/components/MyComponent.vue -->
<template>
  <div class="my-component">
    <p>This text will adapt to dark and light themes.</p>
  </div>
</template>
<style scoped>
.my-component {
  background-color: var(--bg-color);
  color: var(--text-color);
}
</style>

Additional Tips

  • Detect System Preference: You can also use the window.matchMedia API to detect the system’s color scheme on initial load.
  • CSS Transitions: Add transitions to color properties for smoother switching:cssCopy codebody { transition: background-color 0.3s ease, color 0.3s ease; }

With this approach, you can easily switch between dark and light modes in a Vue 3 + TypeScript app with CSS styling.

Leave a Reply

Your email address will not be published. Required fields are marked *