Dark Mode

Apply dark mode and respect saved or system appearance preferences

StellarAdmin supports dark mode, which can be applied by adding the dark CSS class on a containing element such as the <html> or <body> element. All the content of that element will then render in dark mode. The StellarAdmin stylesheet carries both modes, and a theme derives its dark mode from the same CSS variables, so there is nothing else to add.

<html lang="en" class="dark">

You can render it server-side from a saved user preference, or toggle it on the client. The script below demonstrates a minimal client-side approach that honors a saved choice and falls back to the operating system setting. Place it in <head>, before the stylesheets.

<script>
    (function () {
        var saved = null;
        try { saved = localStorage.getItem("theme"); } catch (e) { }
        var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
        var dark = saved === "dark" || (saved !== "light" && prefersDark);
        document.documentElement.classList.toggle("dark", dark);
        document.documentElement.style.colorScheme = dark ? "dark" : "light";
    })();
</script>

Setting color-scheme alongside the class keeps native controls such as scrollbars and form elements in step with the page.

Part of a page

The class also works on part of a page: a dark element inside a light page renders its content in dark mode, such as a dark promotion or a dark sidebar beside light content. The light class does the opposite, switching part of a dark page back to light mode. Each stops at the other, so they nest: a dark element inside a light one inside a dark page is dark again.

The sections below set their background with bg-background from the Tailwind adapter, which is the page colour in that section's mode; without Tailwind CSS, use background: var(--sa-color-canvas). Whichever mode this site is in, one of them stands out.

<div class="flex w-full flex-col gap-6">
    <section class="dark flex flex-col gap-4 rounded-xl bg-background p-6 text-foreground">
        <div class="flex flex-col gap-1">
            <h3 class="text-lg font-semibold">Northern lights in Tromsø</h3>
            <p class="text-sm text-muted-foreground">Four nights under the aurora, with a guided night hunt and a husky ride.</p>
        </div>
        <div class="flex flex-wrap items-center gap-2">
            <sa-input class="w-56" placeholder="Your email address"/>
            <sa-button>Notify me</sa-button>
            <sa-button variant="ButtonVariant.Ghost">Learn more</sa-button>
        </div>
    </section>

    <section class="light flex flex-col gap-4 rounded-xl bg-background p-6 text-foreground">
        <div class="flex flex-col gap-1">
            <h3 class="text-lg font-semibold">Midsummer in Stockholm</h3>
            <p class="text-sm text-muted-foreground">Three nights of near-endless daylight, with an archipelago cruise and a Midsummer Eve feast.</p>
        </div>
        <div class="flex flex-wrap items-center gap-2">
            <sa-input class="w-56" placeholder="Your email address"/>
            <sa-button>Notify me</sa-button>
            <sa-button variant="ButtonVariant.Ghost">Learn more</sa-button>
        </div>
    </section>

    <div class="flex flex-wrap items-center gap-2">
        <sa-input class="w-56" placeholder="Your email address"/>
        <sa-button>Notify me</sa-button>
        <sa-button variant="ButtonVariant.Ghost">Learn more</sa-button>
    </div>
</div>

On this page