Colors and High Contrast Mode
Firefox offers several customisations to improve the accessibility of colors used to render web content and Firefox chrome. This document describes the customisation options available and their behaviour across platforms. It also describes how these options interact with one another. It is intended for developer reference :)
The Contrast Control Settings
In about:preferences > Language and Appearance
, you’ll find a subsection labeled “Contrast Control”. The radio group in this section determines if high contrast mode (HCM) will be used. HCM can either be enabled on the platform level (OS HCM), or forced on in the browser (FF HCM)
The radio buttons alter browser.display.document_color_use
. HCM can be enabled automatically with OS settings (OS HCM, document_color_use=0
), it can be forced off (document_color_use=1
), or forced on (FF HCM, document_color_use=2
). When HCM is enabled, either automatically or explicitly, web content is rendered with a predetermined palette to give the user full control of the content’s color contrast.
Note: FF HCM only affects web content, so changing the option in this select will only alter color usage for web pages. It will not change FF chrome. Current behaviour on chrome pages (ie.
about:
pages) is undefined.
User-customisable Colors Dialog
If the user has chosen to explicitly turn on Firefox HCM (document_color_use=2
), they may customize the palette in a modal dialog. Users can choose to override background color, foreground color, visited link color, and/or unvisited link color by selecting a new color from the color inputs in the dialog. Modifications to these colors are stored in their corresponding user preference:
browser.background_color
browser.foreground_color
browser.visited_color
browser.anchor_color
Color Usage and System Colors
Before we render any Firefox/web content, we need to select a color palette to render that content with. There are three different sets of colors we can use to style Firefox and/or web content:
Stand-in colors
System colors
Colors-dialog colors
Note: Web pages may supply their palette through style sheets. When FF HCM is set to “On”, or set to “Use platform’s contrast settings” and OS HCM is enabled, the chosen color palette is forced, meaning it cannot be overridden by web pages.
We decide which set of colors to use in PreferenceSheet::Load
. If resistFingerprinting
is enabled, we use stand-in colors. These colors are pre-defined constants and are not dynamically fetched from the operating system. Check out nsXPLookAndFeel::GetStandinForNativeColor
for more information, as well as the constants themselves.
If we aren’t using stand-in colors, we’ll check the browser.display.document_color_use
pref. If HCM is explicitly off (1
), or automatically off (0
), we will use the system colors as default text and link colors.
System colors are colors queried from the operating system. They help Firefox adapt to OS-level changes that aren’t strictly HCM (ie. light/dark themeing). Because these colors are OS-dependent, a user operating Firefox on a Windows machine with system colors enabled will see Firefox differently than a user with system colors enabled on MacOS.
So, how do we get system colors? Our style system has a set of pre-defined ColorID
’s in ServoStyleConsts.h
, which are mapped to platform-specific colors in widget/[cocoa | android | windows | gtk]/LookAndFeel.cpp
. Depending on the ColorID
queried, we may do a dynamic fetch or simply return a constant. On MacOS, for example, ColorID::TextForeground
and ColorID::TextBackground
are hard-coded to return black and white respectively. ColorID::Highlight
, on the other hand, queries the OS for NSColor.selectedTextBackgroundColor
, which is set based on the accent color a user has selected in System Preferences.
Note: The colors we fetch here are theme-relative. If a user has set their OS to a dark theme, we’ll fetch colors from that palette, and likewise for a light theme. Windows HCM, though not strictly a “theme”, overrides the colors stored for Windows’ light theme, leading to some confusing code, like this.
Lastly, if we explicitly turn on HCM (document_color_use=2
) AND we are not styling Firefox chrome AND we are not resistFingerprinting
, we’ll use colors-dialog colors to style web content.
By default, browser.display.document_color_use
is set to 2
on Windows. If a user turns on the OS HCM Firefox will automatically go into HCM mode as well.
Note: This is intentional. Windows HCM is the most robust HCM offered among the operating systems we support, and so we cater to it here :)
Users on non-Windows platforms have HCM disabled by default (document_color_use=1
). In order to enable Firefox HCM, they will either need to turn
it on explicitly (document_color_use=2
), or set it to use the OS HCM mode and palette (document_color_use=0
).
For a simplified flow chart of this decision tree, check out our HCM Settings page
High Contrast Mode
Operating System High Contrast Mode (OS HCM)
Operating System HCM (or OS HCM) describes a high contrast customisation that is enabled outside of Firefox, in the settings of a user’s operating system. Each of our major desktop operating systems has an OS HCM variant:
Windows: Settings > Accessibility > Increase Contrast > (select theme) > Apply
MacOS: System Preferences > Accessibility > Display > Increase Contrast
Linux: Settings > Themes > High Contrast
The presence of an OS HCM is stored in IntID::UseAccessibilityTheme
.