Skip to content

Dark mode#21617

Closed
adrianoracano wants to merge 2 commits into
mozilla:masterfrom
adrianoracano:dark_mode
Closed

Dark mode#21617
adrianoracano wants to merge 2 commits into
mozilla:masterfrom
adrianoracano:dark_mode

Conversation

@adrianoracano

Copy link
Copy Markdown

Smart Page Dark Mode for PDF Viewer

This PR adds a smart dark mode feature for PDF page content in the viewer, with two distinct modes that preserve images and graphics rather than applying a naive full inversion.

Motivation

Reading PDFs with bright white backgrounds causes eye strain in low-light environments. The existing viewerCssTheme option controls the UI chrome theme (toolbar, sidebar, dialogs) but does not affect the rendered page content. This PR fills that gap with a content-aware dark mode that only affects the page canvas and thumbnails, leaving UI components to follow the system theme independently.

Dark Mode Modes

A new pageDarkMode option (persisted as a viewer preference) supports three states:

Mode Value Filter Behavior
Off 0 none Pages render normally
Soft 1 brightness(0.85) contrast(0.95) Slightly darkens white backgrounds; images and graphics are virtually untouched
Full 2 invert(0.88) hue-rotate(180deg) Full dark mode with hue rotation to approximately restore image colors (same technique used by Adobe Acrobat)

Both modes are "smart" — they use CSS filters that handle images and graphics gracefully, unlike a crude invert(1) which would turn photos into photographic negatives.

Scope

The dark mode filter is applied only to:

  • .canvasWrapper canvas — the rendered PDF page canvases
  • .thumbnailsView .thumbnailImageContainer img — the thumbnail images in the sidebar

The toolbar, sidebar, menus, dialogs, and all other UI chrome are not affected and continue to follow the OS-level color-scheme preference (or the explicit viewerCssTheme setting).

UX

A new "Page Dark Mode" button (moon icon) has been added to the secondary toolbar (the tools dropdown). Each click cycles through Off → Soft → Full → Off. The button label updates to indicate the active mode (e.g. "Page Dark Mode: Soft").

Files Changed

File Change
web/app_options.js Added pageDarkMode option (0/1/2, persisted as a preference)
web/app.js Added _togglePageDarkMode() and _applyPageDarkMode() methods; wired up event listeners and initial preference application
web/pdf_viewer.css Added --page-dark-mode-filter CSS custom property; applied it as a filter to canvas elements and thumbnail images
web/viewer.css Added --secondaryToolbarButton-pageDarkMode-icon variable and button icon mask rule
web/viewer.html Added the dark mode toggle button to the secondary toolbar
web/viewer.js Registered pageDarkModeButton in getViewerConfiguration()
web/secondary_toolbar.js Added button event dispatch (togglepagedarkmode)
l10n/en-US/viewer.ftl Added English translation strings
web/images/secondaryToolbarButton-pageDarkMode.svg New — Moon icon for the dark mode button

How It Works

  1. The user clicks the dark mode button in the secondary toolbar
  2. secondary_toolbar.js dispatches a togglepagedarkmode event
  3. app.js handler cycles the pageDarkMode AppOption (0→1→2→0)
  4. AppOptions.set() triggers a pagedarkmode event via EVENT_DISPATCH
  5. _applyPageDarkMode() sets the --page-dark-mode-filter CSS variable on the viewer and thumbnail containers
  6. CSS rules on canvas and thumbnail images pick up the variable and apply the corresponding CSS filter
  7. On subsequent loads, the saved preference is restored automatically

@adrianoracano
adrianoracano requested a review from a team as a code owner July 21, 2026 23:25
@flodolo
flodolo removed the request for review from a team July 22, 2026 05:03
@flodolo

flodolo commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

I'm taking this out of the l10n queue for now, as there is no issue or bug attached justifying this work.

@Snuffleupagus

Copy link
Copy Markdown
Collaborator

Sorry, but features such as this requires feedback and a design specification from Firefox UX/UI before any work can start.

(Also, given that AI was used to write #21617 (comment) there'd also be the question if that applies to all of the code as well.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants