Nowadays all modern websites are providing an option to change a default design into its dark mode version. Somehow this trend becomes a standard and there are several approaches how to achieve this behavior.
Below we will look at the basic implementation in Django without using any Python code (just templates) in combination with Tailwind CSS and Alpine.js. Tailwind CSS will provide a visual style for the default design and dark move version. Alpine.js will be responsible for the dynamic part of switching between these two modes.
First of all, let's start with the basic configuration of Tailwind CSS. The prerequisite is that tailwind.config.js
file is already available with appropriate configuration options. Everything that is needed to do now, is to add darkMode
option. This will tell Tailwind to switch the styles based on dark
CSS class, in our cases available on body
element.
// tailwind.config.js
module.exports = {
darkMode: "class",
};
// templates/skeleton.html
{% load static %}
<html>
<head>
<link href="{% static 'css/styles.css' %}" rel="stylesheet">
</head>
<body>
{% block content %}{% endblock }
</body>
</html>
There is one more additional thing, which is required to be added into custom Tailwind styles. When the page is loaded, there is short blib of different styles before. It is visible when the dark mode is enabled but for the short period of time original theme is display. This can be fixed be creating selector below and then applying it on body
element.
/* styles.css */
[x-cloak] {
@apply !hidden;
}
For the dynamic part of the application, it is necessary to load Alpine.js library. In this example, CDN version is going to be good enough but in your custom application, the script can be downloaded into static/
folder and then loaded via {% static %}
template tag.
On top of that, one additional Alpine.js library is required which is going to be responsible for persisting current theme selection into local storage. Below you can see the new version of html
element, adding these libraries.
<head>
<link href="{% static 'css/styles.css' %}" rel="stylesheet">
<script
defer
src="https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js"
></script>
<script
defer
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
></script>
</head>
The currently implemented switcher is going to have three available options. The first option is the default light mode version of the website, the second option is the dark mode version. The third version is "auto", based on current system settings default theme is going to be selected, it can be light or dark.
Our application, as was already mentioned, is going to store this information in local storage by using Persist, Alpine.js library. The selected option is available in local storage, under theme
option.
For the whole implementation, just three Alpine.js directives are used. The simplest one is x-cloak
, which will hide website until everything is properly loaded.
Then for initializing the data directive x-data
has to be set to { theme: $persist('auto').as('theme') }
. The value is initializing theme
variable from local storage and in case that key does not exist, value auto
is used.
The last directive is setting proper Tailwind CSS class to html
element. For this purpose x-bind
directive will set proper class attribute base on theme
variable, initialized in previous step via x-data
directive.
// skeleton.html
<html
x-cloak
x-data="{ theme: $persist('auto').as('theme') }"
x-bind:class="{
'dark': theme === 'dark' ||
(theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)
}"
></html>
The last step is to code a toggle navigation inside Django template. For this purpose simple nav
element with links is enough. On each link it is necessary to attach click event by using x-on
directive. Clicking on link will change value of theme
variable. As this variable is coming from persist plugin, it will push value into local storage as well causing that after the page refresh, value will be not lost.
// base.html
{% extends "skeleton.html" %}
{% block content %}
<nav>
<a x-on:click="theme = 'dark'">Dark</a>
<a x-on:click="theme = 'light'">Light</a>
<a x-on:click="theme = 'auto'">System</a>
</nav>
{% endblock %}
Django admin theme built with Tailwind CSS to bring modern look and feel to your admin interface. Already contains several built-in features for smooth developer experience.
© 2023 - 2024 Created by unfoldadmin.com. All rights reserved.