Theme Selection
This website has two independent theme systems: a Bootswatch theme picker for the page layout (navbar, cards, body text) and a syntax theme selector for code block highlighting. Both are persisted in localStorage.
Bootswatch page theme
Uses Bootswatch themes with Bootstrap 5.3's data-bs-theme attribute.
How it works
- A theme dropdown in the navbar lets users switch between all 27 Bootswatch themes
- Selection persisted under
localStoragekeybootswatch-theme - On first visit, defaults to Darkly (dark OS preference) or Flatly (light OS preference) via
prefers-color-scheme - An inline
<head>script applies the theme before first paint to prevent a flash
Theme classification
| Dark (7) | Light (20) |
|---|---|
| Cyborg, Darkly, Quartz, Slate, Solar, Superhero, Vapor | Brite, Cerulean, Cosmo, Flatly, Journal, Litera, Lumen, Lux, Materia, Minty, Morph, Pulse, Sandstone, Simplex, Sketchy, Spacelab, United, Yeti, Zephyr |
Syntax highlighting theme
An independent syntax dropdown in the navbar controls the highlight.js stylesheet. It is separate from the Bootswatch theme — users can mix any page theme with any code theme.
Modes
| Mode | Behaviour |
|---|---|
| Auto (default) | Maps to github-dark-dimmed for dark Bootswatch themes, github for light. Follows the page theme. |
| Manual | Any explicit selection overrides auto. Bootswatch theme changes no longer affect the code theme. |
Persistence
- Key:
localStoragekeyhljs-theme - Absent or
"auto"→ follow Bootswatch dark/light - Any theme name → use that theme independently
Dropdown layout
┌──────────────────────────────────────┐
│ Auto (follow theme) ✓ │
│ ─ ─ ─ ─ ─ ─ │
│ Dark │
│ Atom One Dark │
│ Monokai Sublime │
│ Nord │
│ Dracula │
│ Night Owl │
│ Tokyo Night Dark │
│ ─ ─ ─ ─ ─ ─ │
│ Light │
│ Atom One Light │
│ GitHub │
│ VS │
│ XCode │
│ Tokyo Night Light │
│ IntelliJ Light │
│ ─ ─ ─ ─ ─ ─ │
│ Other (245) │
│ └─ (lazy-loaded on expand) │
│ Hide │
└──────────────────────────────────────┘
Other themes
245 additional themes (all non-base16 + all base16 variants) are embedded as a JS array (window.HLJS_OTHER) in the <head> script. The DOM is generated lazily on first click of "Show all" — avoids rendering 245 nodes on every page load.
Implementation
All logic lives in templates/base.html:
<link id="hljs-css">— dynamically swapped via JS; no static default- Inline
<head>script — defineswindow.HLJS_OTHER,setHljs(theme)function; applies stored choice synchronously - Dropdown menu — curated items hardcoded in HTML; "Other" section generated client-side
- Body script — click handlers for both Bootswatch and syntax dropdowns; Bootswatch handler only updates hljs when in auto mode; syntax handler saves to
localStorageand swaps the CSS link
Theme swap mechanism
Class names are identical across all highlight.js themes (.hljs, .hljs-keyword, etc.). Swapping the <link> href causes the browser to recalculate styles automatically — no need to re-run hljs.highlightAll().
Interaction with Bootswatch
When the user changes the Bootswatch theme: - If hljs is in Auto mode → hljs theme updates to match the new dark/light classification - If hljs is in manual mode → no change
CDN
Bootswatch: https://cdn.jsdelivr.net/npm/bootswatch@5.3.8/dist/{theme}/bootstrap.min.css
highlight.js: https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/{theme}.min.css