Add a global dark mode with Tailwind CSS
Tags: tailwindcss, css, laravel, tutorial
Published: 2023-09-13 13:22:31

TL;DR: How to quickly implement a dark mode with the help of Tailwind CSS and around ten lines of code.

&nbsp;
&nbsp;

You will find a sample Laravel project on this [Github Repository](https://github.com/capsulescodes/articles).

&nbsp;
&nbsp;

The main element of this article is the `dark` variant that can be configured in the Tailwind CSS configuration file. Adding the `class` value to `darkMode` activates the CSS classes only when the `dark` class is present. The `media` value, on the other hand, is based on the operating system's preferences.

&nbsp;

`tailwind.config.js`

```js
export default {
  content: [ ... ],
  darkMode : 'class',
  theme : { ... },
  plugins : [ ... ],
}
```

&nbsp;
&nbsp;

Two CSS classes will modify all elements on the page. These classes are written directly in the **`app.css`** file alongside the Tailwind CSS directives.

&nbsp;

`resources/css/app.css`

```css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components
{
    .dark-mode
    {
        @apply dark:invert dark:-hue-rotate-180 dark:saturate-100 dark:brightness-90;
    }

    .dark-image-mode
    {
        @apply dark:invert dark:hue-rotate-180 dark:saturate-[1.25];
    }
}
```

&nbsp;
&nbsp;

The `dark-mode` class is the one that inverts the entire page, including the images. To preserve certain images from these modifications, we assign them the `dark-image-mode` class. The role of this latter class is to neutralize the changes made by the `dark-mode` class.

&nbsp;
&nbsp;

The addition of dark mode is determined by the `dark` class applied here to the `body` element in the `welcome.blade.php` file.

&nbsp;

`welcome.blade.php`

```html
<!DOCTYPE html>

<html lang="{{ Str::snake( app()->getLocale() ) }}">

    <head>

        <meta charset="utf-8">

        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Capsules Codes - Set up a global dark mode quickly with Tailwind CSS</title>

        @vite( 'resources/css/app.css' )

    </head>

    <body class="dark">

        <div class="bg-primary-white dark-mode">

            <div class="w-screen h-screen flex justify-center font-sans text-primary-black">

                <div class="flex flex-col items-center justify-center text-center">

                    <img class="w-24 h-24 dark-image-mode select-none" src="/assets/capsules-logotype-red-blue-home.svg" alt="Capsules Codes Logotype">

                    <h1 class="mt-4 text-6xl font-bold select-none header-mode">Capsules Codes</h1>

                    <h2 class="mt-4 text-xl font-extralight tracking-wide">{{ Request::path() !== 'dark-mode' ? 'Light Mode' : 'Dark Mode' }}</h2>

                </div>

            </div>

        <div>

    </body>

</html>
```

&nbsp;
&nbsp;

![capsules-dark-mode-001.jpg](https://capsules.codes/storage/canvas/images/vGddTnNb9g1aek6p4vSBJzpPkM75R1c6rTVZfrxI.jpg)

&nbsp;
&nbsp;

The colors of the page content are now inverted. By adding a button that allows switching between dark mode and light mode, we achieve the expected result.

&nbsp;
&nbsp;

In the context of this article, the sample project is based solely on Blade. The button then calls two routes: `/dark-mode` and `/light-mode`, each indicating to the content whether it should invert the colors of the page or not.

&nbsp;

`web.php` 

```php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/{mode?}', fn() => view( 'welcome' ) );
```

&nbsp;
&nbsp;

`welcome.blade.php`

```php
<body class="{{ Request::path() !== 'dark-mode' ? '' : 'dark' }}">

        <div class="w-screen h-screen relative flex flex-col bg-primary-white dark-mode">

            <div class="absolute w-full h-16 flex items-center justify-center" >

            @if( Request::path() !== 'dark-mode' )

                <a href="/dark-mode" class="p-2 rounded-md outline-none hover:bg-slate-50">

                    <img class="w-6 h-6 dark-image-mode select-none" src="/assets/capsules-sun-icon.svg" alt="Sun icon">

                </a>

            @else

                <a href="/light-mode" class="p-2 rounded-md outline-none  hover:bg-slate-50">

                    <img class="w-6 h-6 dark-image-mode select-none" src="/assets/capsules-moon-icon.svg" alt="Moon icon">

                </a>

            @endif

            </div>

            <div class="grow flex justify-center font-sans text-primary-black">

                <div class="flex flex-col items-center justify-center text-center">

                    <img class="w-24 h-24 dark-image-mode select-none" src="/assets/capsules-logotype-red-blue-home.svg" alt="Capsules Codes Logotype">

                    <h1 class="mt-4 text-6xl font-bold select-none header-mode">Capsules Codes</h1>

                    <h2 class="mt-4 text-xl font-extralight tracking-wide">{{ Request::path() !== 'dark-mode' ? 'Light Mode' : 'Dark Mode' }}</h2>

                </div>

            </div>

        <div>

    </body>
```

&nbsp;
&nbsp;

The elements are then influenced by `Request::path() !== 'dark-mode’`

&nbsp;
&nbsp;

![capsules-dark-mode-dark-002.jpg](https://capsules.codes/storage/canvas/images/hkY42aByvyLJKW1LSrD0iKJhQIJZMq8oSBznmFSK.jpg)

&nbsp;
&nbsp;

Changing the mode using JavaScript allows for a smooth transition from dark mode to light mode via the Tailwind CSS classes `transition-all duration-300 ease-in-out`. These classes can be applied to the new classes `dark-mode` and `dark-image-mode`. The result is much more visually appealing.

&nbsp;
&nbsp;

The `dark-image-mode` class, by reversing the values of the `dark-mode` class, does not return the image to its original colors. The resulting image is slightly duller. The result remains satisfactory.

&nbsp;
&nbsp;

Glad this helped.

&nbsp;
&nbsp;

Find out more on [Capsules](https://capsules.codes) or [X](https://x.com/capsulescodes)