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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions