labb uses daisyUI 5 for themes. Define the colours in input.css, set the active theme on the page, and save a visitor’s choice in their session if you need to.
Connect the theme controls
Start with the <c-lb.m.dependencies /> tag from Installation. Add {% labb_theme %} to the <html> element and give the dependency tag the endpoint that stores a theme choice.
<html lang="en" {% labb_theme %}>
<head>
<c-lb.m.dependencies setThemeEndpoint="{% url 'set_theme' %}" />
</head>
<body>
{% csrf_token %}
from django.urls import path
from labb.shortcuts import set_theme_view
urlpatterns = [
# ... your other URLs
path('set-theme/', set_theme_view, name='set_theme'),
]
{% labb_theme %} writes data-theme="theme-name" to <html>. It reads the user’s session and falls back to LABB_SETTINGS['DEFAULT_THEME']. Keep {% csrf_token %} in the page because the theme controller sends a POST request.
{% labb_theme_val %} when template logic needs the raw value. For example, {% labb_theme_val as current_theme %} stores it in a variable.
Built-in themes
labb init subscribes the project to labb’s themes CSS group. During a build, labb imports that group into .labb/labb.css. Keep the generated import in input.css.
The standard labb themes are labb-light and labb-dark. The starter CSS also enables daisyUI’s light and dark themes.
@import "tailwindcss";
@plugin "daisyui" {
themes: light, dark;
}
/* labb CSS - don't remove this line */
@import "../.labb/labb.css";
Add a custom theme
Add an @plugin "daisyui/theme" block below the generated labb import in input.css. Do not edit .labb/labb.css; labb replaces it on every build. The daisyUI Theme Generator can help you choose values.
@plugin "daisyui/theme" {
name: "my-brand";
default: false;
color-scheme: light;
--color-primary: oklch(55% 0.3 240);
--color-secondary: oklch(70% 0.25 200);
--color-accent: oklch(65% 0.25 160);
--color-base-100: oklch(98% 0.02 240);
--color-base-content: oklch(20% 0.05 240);
--radius-selector: 1rem;
--radius-field: 0.25rem;
--radius-box: 0.5rem;
}
The daisyUI theme documentation lists the available variables.
Add a theme switcher
Add the theme-controller class to a radio control, checkbox, or toggle. With the endpoint configured, labb posts the selected value to Django.
Themed surface
Every colour here comes from the theme, so this card follows the toggle.
<div class="flex flex-col gap-4 w-full max-w-sm">
<div class="flex items-center gap-3">
<c-lb.toggle class="theme-controller" value="dark" size="sm" title="Toggle dark mode" />
<span class="text-sm text-base-content/70">Switch to dark mode</span>
</div>
<c-lb.card border>
<c-lb.card.body>
<c-lb.card.title>Themed surface</c-lb.card.title>
<p class="text-sm text-base-content/60">
Every colour here comes from the theme, so this card follows the toggle.
</p>
<c-lb.card.actions>
<c-lb.button variant="primary" size="sm">Primary</c-lb.button>
<c-lb.button btnStyle="ghost" size="sm">Ghost</c-lb.button>
</c-lb.card.actions>
</c-lb.card.body>
</c-lb.card>
</div>
<!-- Toggle dark mode -->
<c-lb.toggle class="theme-controller" value="dark" size="sm" title="Toggle dark mode" />
<!-- A checkbox works too -->
<c-lb.checkbox class="theme-controller" value="dark" title="Dark mode" />
See the Theme Controller component documentation for more examples.
Choose the default
LABB_SETTINGS = {
'DEFAULT_THEME': 'labb-light', # Fallback when no theme is set
}
See settings reference for all options.
Write a custom view
set_theme_view.
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from labb.shortcuts import set_labb_theme, get_labb_theme
from labb.contrib.theme import is_valid_theme_name
@require_http_methods(["POST"])
def set_theme(request):
theme = request.POST.get("theme")
if not theme:
return JsonResponse({"success": False, "error": "Theme parameter is required"}, status=400)
if not is_valid_theme_name(theme):
return JsonResponse({"success": False, "error": "Invalid theme name"}, status=400)
success = set_labb_theme(request, theme)
if success:
return JsonResponse({"success": True, "theme": theme})
return JsonResponse({"success": False, "error": "Failed to set theme"}, status=500)
Import these functions from labb.shortcuts.
set_labb_theme(request, theme)stores the theme in the session and returnsTrueorFalseget_labb_theme(request)returns the current session valueset_theme_viewprovides the built-in persistence view
set_labb_theme stores whatever you give it. The theme name ends up in a data-theme attribute and in a
CSS selector, so check it first. set_theme_view already does; a custom view should call
is_valid_theme_name as above.
Fix common problems
- The theme does not apply. Run
labb buildand confirm that the CSS and HTML use the same theme name. - The selection does not persist. Put
{% csrf_token %}in<body>and setsetThemeEndpointon<c-lb.m.dependencies />. - Styles do not update. Refresh the browser without its cache, then restart
labb dev.
Related
Building CSS
Why a theme change needs a rebuild
settings.py
DEFAULT_THEME and the rest of LABB_SETTINGS
Explore blocks
Useful references include daisyUI themes, the theme generator, and an OKLCH colour picker.