In this post, you'll learn how to implement a Light and Dark theme with AlpineJS and TailwindCSS. The modes can be toggled on and off and the state will be persisted locally on the browser local storage.
Let's start by installing the library and here you can use "npm" or "yarn" package manager.
Install AlpineJS and Tailwind CSS
Let's start by installing the library and here you can use "npm" or "yarn" package manager.
//alpine js npm install alpinejs // tailwind css npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
If you are working on a Laravel project, you can refer to my other tutorial for the full guide to Setting Up Apline Js for the Laravel 8 project. Do note that you can't use TailwindCSS CDN since some additional configuration is needed for the dark mode customization.
To enable the dark mode variant, update the tailwind config file and add "darkMode" settings and set it to have "class" as the value.
Enable Tailwind CSS Dark Mode Variant
To enable the dark mode variant, update the tailwind config file and add "darkMode" settings and set it to have "class" as the value.
// tailwind.config.js module.exports = { darkMode: 'class', }
Create a Card Component
For this example let's create a card component and apply the light and dark modes for it but the concepts are the same to theme an entire page, so let's get started.
<div class="h-screen flex justify-center items-center bg-gray-50"> <div class="w-full sm:w-8/12 md:w-6/12 p-4"> <div class="p-4 rounded-lg shadow bg-white"> <h1 class="font-semibold text-lg"> Card Heading </h1> <p class="mt-2"> This is the content of the card </p> <button class="mt-2 px-3 py-2 bg-pink-400 rounded-lg font-semibold text-white"> Toggle Modes </button> </div> </div> </div>
The preview of the card component will look like below.
To add the dark variant for the card component, you can use the "dark:" to style the corresponding light theme. Refer to the example below.
Before (only light variant)
Card Component Dark Variant
To add the dark variant for the card component, you can use the "dark:" to style the corresponding light theme. Refer to the example below.
Before (only light variant)
<div class="p-4 rounded-lg shadow bg-white"></div>
After (now contain dark variant)
<div class="p-4 rounded-lg shadow bg-white dark:bg-gray-700"></div>
The full code of the dark variant will look like below.
<div class="h-screen flex justify-center items-center bg-gray-50"> <div class="w-full sm:w-8/12 md:w-6/12 p-4"> <div class="p-4 rounded-lg shadow bg-white dark:bg-gray-700"> <h1 class="font-semibold text-lg dark:text-gray-200"> Card Heading </h1> <p class="mt-2 dark:text-gray-200"> This is the content of the card </p> <button class="mt-2 px-3 py-2 bg-pink-400 rounded-lg font-semibold text-white"> Toggle Modes </button> </div> </div> </div>
Bind the Toggle with Alpine JS
Now since we have the light and dark mode variant set up, let's bind the button with Alpine JS. The full code can be referred from below.
<div class="h-screen flex justify-center items-center bg-gray-50"> <div class="w-full sm:w-8/12 md:w-6/12 p-4"> <div class="p-4 rounded-lg shadow bg-white dark:bg-gray-700"> <h1 class="font-semibold text-lg dark:text-gray-200"> Card Heading </h1> <p class="mt-2 dark:text-gray-200"> This is the content of the card </p> <button x-data="{ toggle: () => { if (localStorage.theme === 'dark') { localStorage.theme = 'light'; document.documentElement.classList.remove('dark'); } else { localStorage.theme = 'dark'; document.documentElement.classList.add('dark'); } }, }" class="mt-2 px-3 py-2 bg-pink-400 rounded-lg font-semibold text-white focus:outline-none" @click="toggle" > Toggle Modes </button> </div> </div> </div>
How the toggle work is that every time it's clicked, the local storage is checked to see if there's a "theme" with a "dark" value. If the value is present then the theme is set to light and remove any existing class from the document "HTML" tag.
localStorage.theme = 'light'; document.documentElement.classList.remove('dark');
Otherwise, if the value is already "light", then add the "dark" theme and set the "HTML" tag to have the class.
localStorage.theme = 'dark'; document.documentElement.classList.add('dark');
Respect Operating System Color Preference
If by default you want the page to respect the operating system color preference, you can add the code below. So if by default the user operating system is using dark mode, the page will set the page to dark otherwise it will be light.
// On page load or when changing themes, best to add inline in `head` to avoid FOUC if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { document.documentElement.classList.add('dark') } else { document.documentElement.classList.remove('dark') } // Whenever the user explicitly chooses light mode localStorage.theme = 'light' // Whenever the user explicitly chooses dark mode localStorage.theme = 'dark' // Whenever the user explicitly chooses to respect the OS preference localStorage.removeItem('theme')
Leave a reply