Skip to content

Feature Request: Persistent Light/Dark Theme Toggle with Code Styling #1736

Description

@funketyme

NOTE: I have already implemented this and am creating this issue to reference in an associated pull request.

Summary

Add a dark mode toggle to CFDocs that:

  • appears as a sun/moon icon in the navbar
  • persists the user’s choice via localStorage
  • respects OS prefers-color-scheme when no manual choice is set
  • uses CSS custom properties for theme colors

Implementation

JavaScript

theme-switcher.js

  • Defines LIGHT_THEME and DARK_THEME
  • Reads stored preference from localStorage
  • Falls back to window.matchMedia('(prefers-color-scheme: dark)')
  • Applies theme by setting document.documentElement.dataset.theme
  • Adds keyboard accessibility to the toggle button
  • Watches OS theme changes and updates only if the user has not overridden theme manually

CSS

style.css

  • Uses :root custom properties for light mode defaults
  • Uses @media (prefers-color-scheme: dark) to set dark mode variables for OS preference
  • Uses [data-theme="dark"] and [data-theme="light"] to manually override theme
  • Uses var(--...) throughout the stylesheet so color changes propagate consistently
  • Adds a black background for light-mode pre.prettyprint examples so code blocks look intentional
  • Removes nested inline span backgrounds inside dark-mode prettify blocks so text sits on solid black
  • Adds dark-mode inversion for the #foundeo logo graphic

Layout

layout.cfm

  • Injects the theme switch button into the navbar
  • Includes the theme-switcher.js script

Best Practices Used

  • Use CSS custom properties for theming
  • Prefer data-theme attribute over ad-hoc body classes
  • Keep light mode default and separate dark overrides cleanly
  • Respect OS preferences unless user has explicitly chosen a mode
  • Persist user preference with localStorage
  • Minimize layout changes and avoid touching layout markup unnecessarily
  • Keep dark-mode overrides scoped and specific, especially when overriding Bootstrap
  • Make the toggle keyboard accessible with role="button" and tabindex="0"
  • Use !important only for required Bootstrap override cases

Files Touched

  • theme-switcher.js
  • style.css
  • layout.cfm

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions