Syntax highlighting theme that follows system preference for dark mode

Purpose

We recently introduced an option to automatically switch between light and dark mode based on system preferences. This does not extend to syntax highlighting, which leads to situations in which users cannot read code snippets comfortably when the syntax highlighting theme doesn't match their current mode.

Problem

When users enable the automatic light/dark mode switching based on system preferences, the syntax highlighting theme remains static regardless of the current display mode. This creates readability issues, particularly when a light syntax theme is displayed in dark mode or vice versa.

Proposal

Add the ability for users to select separate syntax highlighting themes for light and dark modes:

  • Allow users to select different syntax highlighting themes for light and dark modes independently
  • When GitLab switches between light and dark mode (either manually or via system preferences), the appropriate syntax highlighting theme will be applied automatically
  • Maintain backward compatibility by migrating existing users' current theme selections to both light and dark mode options initially

Technical Approach

  • Modify the existing database structure to store both light and dark mode syntax highlighting preferences
  • Update the preferences UI to allow selection of themes for each mode (final design TODO)
  • Implement the logic to load the appropriate theme based on the current display mode

Benefits

  • Gives users more control over their visual experience
  • Aligns with user expectations based on experiences with other development tools like VS Code
  • A separate choice for light and dark, rather than an 'auto' syntax highlighting theme, has the highest chance of satisfying everyone using the existing themes and requires no new concept of auto theme to explain in the UI

Considerations

  • For existing users, maintain their current theme selection for both modes to avoid disruption
  • For new users, set appropriate defaults for both light and dark modes
  • Consider how this approach would scale if additional modes (like dimmed or high-contrast) are added in the future — suggestion is to treat light and dark as overarching concepts, with dimmed and high-contrast as extensions of these #470413 (comment 2479854175)

Solution design

Before After After (auto)
image.png image.png image.png

→ Figma

Change highlights

  • Strengthen links between interdependent preferences by reordering options.
  • Update UI text to reflect current terminology and remove circular references.
  • When auto appearance is selected:
    • Show separate light and dark syntax highlighting theme preferences
    • Show separate light and dark previews for diff color

UI text updates

Before After

Appearance

Choose the appearance of the application.

Mode

Choose a color mode.

Syntax highlighting theme

Choose the syntax highlighting theme used when viewing or editing code in GitLab. Learn more.

Syntax highlights

Choose a highlight color scheme for viewing and editing code.

Diff colors

Customize the colors of removed and added lines in diffs. Learn more.

Diffs

Choose a color scheme for removed and added lines in diffs.

Navigation theme

Choose the navigation theme.

Navigation

Choose a color scheme for navigation.

Values

Default values:

  • Existing accounts: One time match syntax theme for light and dark mode.
  • New accounts: Default to light theme for light appearance, dark theme for dark appearance.

Remembering values:

Although the preferences should only display when auto is selected, they should be remembered if the user changes appearance mode. For example:

  • User creates a new account and changes appearance to auto. Syntax themes are light and dark.
  • User changes syntax theme to Solarized light in light, and Monokai in dark. Syntax themes are Solarized light and Monokai.
  • User changes appearance to dark. Syntax theme is Monokai.
  • User changes appearance to light. Syntax theme is Solarized light.
  • User changes syntax theme to Solarized dark . Syntax theme is Solarized dark.
  • User change appearance to auto. Syntax themes are Solarized dark and Monokai.

Improvements to syntax theme preview display

In all situations we can refine the syntax theme preview's on smaller screens.

diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index bdd44063db2c..92007e362324 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -54,7 +54,7 @@
     - c.with_body do
       .syntax-theme.row
         - Gitlab::ColorSchemes.each do |scheme|
-          %label.col-6.col-sm-4.col-md-3.col-lg-auto.gl-mb-5
+          %label.col-6.col-sm-3.col-md-2.col-lg-auto.gl-mb-5
             .preview= image_tag "#{scheme.css_class}-scheme-preview.png", alt: "#{scheme.css_class} scheme preview"
             = f.gitlab_ui_radio_component :color_scheme_id, scheme.id,
               scheme.name,
Edited by Dan MH