Adding Dark Mode

Published Sat Feb 17 2024 Updated Wed Feb 21 2024

When I published this I wasn’t sure what to write here. So I added dark mode to the site :)

I am using TailwindCSS dark mode which is set up to check your device’s theme preference. Once enabled, I just had to add a dark: equivalent color for all my styles. For example, text-rosePineDawn-text gains dark:text-rosePineMoon-text to apply my dark mode palette in dark mode.

Conditional CSS Import

The most difficult part was adding a conditional import for my prism css theme. This is important because it sets the colors for my code blocks with syntax highlighting. Reading the @import docs made me rule out a CSS solution pretty quick since @import statements must be at the top of the file and cannot be nested. Turns out there is a syntax to merge the two! Adding these lines to my app.css handles loading a dark mode stylesheet:

@import 'rosePine-light-prism.css' screen;
@import 'rosePine-dark-prism.css' screen and (prefers-color-scheme: dark);

This solution is elegant and does exactly what you want it to. Before I landed here I had a mess of Svelte code that was handling these imports. The big issue with this approach (aside from not being 2 lines long) is it would load both stylesheets instead of just one.

<script lang="ts">import { onMount } from "svelte";
import LightPrismTheme from "$lib/light-prism-theme.svelte";
import DarkPrismTheme from "$lib/dark-prism-theme.svelte";
let theme = "light";
onMount(() => {
  theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
});
</script>

{#if theme === 'light'}
	<LightPrismTheme />
{:else}
	<DarkPrismTheme />
{/if}

The <LightPrismTheme/> and dark theme loader are simply scripts for importing css:

<script>
	import '../rosePine-light-prism.css';
</script>