How Chromium Implements Forced Colors Mode for Windows

This article explains the technical architecture behind Chromium’s implementation of Forced Colors Mode, a feature designed to seamlessly integrate Windows High Contrast themes into web content. It covers how the browser detects operating system accessibility settings, translates native Windows color palettes into standardized CSS system colors, and uses the Blink rendering engine to strip and override web author styles. Finally, it examines how Chromium maintains text readability over complex backgrounds and gives developers control over specific elements using modern CSS properties.

Operating System Detection

Chromium bridges the gap between the Windows operating system and web content through its native theme layer (ui::NativeThemeWin). The browser actively monitors Windows system events, specifically listening for the WM_THEMECHANGED and WM_SYSCOLORCHANGE messages.

Using the Windows API function SystemParametersInfo with the SPI_GETHIGHCONTRAST flag, Chromium detects the exact moment a user enables a High Contrast theme. Once detected, the browser updates its internal state and notifies the Blink rendering engine to enable Forced Colors Mode and trigger the @media (forced-colors: active) media query.

Mapping Windows Colors to CSS System Colors

When High Contrast is active, Chromium retrieves the specific color palette defined by the user in Windows settings using the GetSysColor API. To adhere to W3C web standards and maintain user privacy, Chromium does not expose raw Windows APIs directly to the web. Instead, it maps these OS-level colors to standardized CSS System Colors:

  • Windows COLOR_WINDOW maps to CSS Canvas (backgrounds).
  • Windows COLOR_WINDOWTEXT maps to CSS CanvasText (body text).
  • Windows COLOR_HOTLIGHT maps to CSS LinkText (hyperlinks).
  • Windows COLOR_GRAYTEXT maps to CSS GrayText (disabled elements).
  • Windows COLOR_HIGHLIGHT and COLOR_HIGHLIGHTTEXT map to CSS Highlight and HighlightText (selected text).
  • Windows COLOR_BTNTEXT and COLOR_BTNFACE map to CSS ButtonText and ButtonFace (UI controls).

This mapping ensures that semantic HTML elements automatically receive the exact colors the user configured in their operating system.

Once the color map is established, the Blink rendering engine alters how it resolves CSS. Rather than simply injecting a high-specificity stylesheet, Blink enforces Forced Colors Mode directly within its StyleResolver and ElementRuleCollector components during the CSS cascade phase.

Chromium intercepts specific CSS properties defined by the website author and forces them to revert to the user agent's default values, which are dynamically bound to the CSS System Colors. The overridden properties include:

  • color
  • background-color
  • border-color
  • outline-color
  • column-rule-color
  • text-decoration-color
  • webkit-tap-highlight-color
  • fill and stroke (in specific User Agent contexts)

Additionally, to eliminate visual clutter that reduces contrast, Chromium forces box-shadow and text-shadow to none. It also removes author-defined background-image properties on certain interactive elements (like buttons and links) to ensure their boundaries and text remain clearly visible.

The Text Backplate Mechanism

Because Forced Colors Mode does not strip background-image from standard div or body containers, text can still end up sitting on top of a complex image, making it unreadable.

To solve this, Chromium implements a "backplate" in its painting phase. As the layout tree is painted, Chromium identifies paragraphs and clusters of text. It then draws a solid rectangle using the Canvas system color directly behind the text nodes, sitting on a layer between the text and any underlying images. This guarantees strict adherence to the user's contrast requirements without deleting informative background images from the webpage.

Handling Developer Opt-Outs

There are scenarios where forcing colors breaks the core functionality of the content, such as color swatches on an e-commerce site or syntax highlighting in a code editor. Chromium implements the forced-color-adjust CSS property to handle these exceptions.

During style calculation, if Blink encounters forced-color-adjust: none on an element, it disables the Forced Colors cascade overrides for that specific element and its descendants, restoring the web author's original CSS. Chromium also automatically applies forced-color-adjust: preserve-parent-color to SVG elements by default. This ensures that vector icons inherit the high-contrast text color of their parent element without having their internal paths and multi-colored fills completely washed out by global overrides.