Background
High contrast mode is a special rendering mode on Windows that applies forced colors and simplifies visual elements throughout the entire platform. This mode is an accessibility feature of Windows and used by people with low vision or visual acuity issues. High contrast mode severely changes the way that websites are rendered on all Windows browsers.
The following CSS properties are overwritten by the theme's system colors:
- color
- background-color
- text-decoration-color
- text-emphasis-color
- border-color
- outline-color
- column-rule-color
- -webkit-tap-highlight-color
- SVG fill attribute
- SVG stroke attribute
Additionally, the following CSS properties are set to none
:
- box-shadow
- text-shadow
- background-image (unless it is a URL)
References
- Enabling high contrast and customizing it (Windows 10 & 11)
- Styling Edge for Windows high contrast mode
forced-colors
media query (Modern browser support)-ms-high-contrast
media query (IE11 and Legacy Edge support)- forced-colors W3C standards
Rendering native elements and system colors
Default | HC Chrome/Edge | HC Firefox |
---|---|---|
Rendering specifics
System colors
Chromium-based browsers (Edge and Chrome) and Firefox both respect the forced color and style adjustments of Windows in high contrast mode. Both browsers types use the system colors rather than user specified colors for most elements. The system colors names and specification is often seen as deprecated, but that is the recommended way to specify a color and have it work in high contrast mode. The table below shows the system color name and its purpose. The system color names are case insensitive. Canvas
and CanvasText
are meant to replace Window
and WindowText
. However, all of them are currently supported in both browser types on Windows. System colors are not set in CSS but rather set in the Windows theme controls and then can be used as colors in CSS.
System Color | Purpose |
---|---|
ActiveText | Text of active links |
ButtonBorder | Base border color of controls |
ButtonFace | Background color of controls |
ButtonText | Foreground color of controls |
Canvas | Background of application content or documents |
CanvasText | Foreground color in application content or documents |
Field | Background of input fields |
FieldText | Text in input fields |
GrayText | Foreground color for disabled items (e.g. a disabled control) |
Highlight | Background of selected items |
HighlightText | Foreground color of selected items |
LinkText | Text of non-active, non-visited links |
VisitedText | Text of visited links |
Window | Window background |
WindowText | Text in windows |
Media queries
A simple media query can determine if the page is being rendered in high contrast mode or not. The recommended way to determine this is to use the forced-colors
media query. The deprecated -ms-high-contrast
query still works on Edge, but is expected to be removed "soon". If you are still supporting Internet Explorer or Legacy Edge then you would want to use this deprecated media query. For example, this snippet would set the color
and background-color
of an element with a selected
class to be the inverse of a "normal" element on the page only when the system is in high contrast mode.
@media (forced-colors: active) {
.selected {
background-color: CanvasText;
color: Canvas;
}
}
There is an escape hatch that should be used very sparingly. Setting a CSS selector to forced-color-adjust: none
opts out of the high contrast color mode. While it may seem tempting to do this where ever high contrast mode is causing UI problems, it is not a recommended practice. Users have turned on high contrast mode for a reason. You should work with it if at all possible.
UPDATE - forced-colors
emulation now available
As of Chromium 98 (both Chrome 98 and Edge 98) you can set forced-colors: active
in the "Rendering" pane of DevTools.
Browser differences
While both browser types render high contrast, there are some obvious differences between the browsers. The most obvious difference is in rendering SVGs with a fill
of currentColor
. Chrome and Edge on Windows have a specific user-agent style for SVG that sets forced-color-adjust: none
. This allows one to easily set the color on an SVG in those browsers. However, there is no guaranty that the SVG will have appropriate contrast or even be visible. On Firefox, SVG's currentColor is forced to the WindowText/CanvasText color. This ensures that the icon is visible, but eliminates any color information that the SVG is expected to convey.
Another, less obvious difference is that Chrome and Edge also set the value of the prefers-color-scheme
in high contrast mode depending on the Window/Canvas color used by the high contrast theme. High contrast themes with backgrounds below a certain luminosity get prefers-color-scheme: dark
while background values above that threshold get prefers-color-scheme: light
set, regardless of other system preferences. This is not the case in Firefox, which follows the system preference and defaults to prefers-color-scheme: light
regardless of the actual theme colors. Because of the way that Firefox overwrites SVG currentColor
along with the other rendering changes, the value of prefers-color-scheme
has little impact on what the user sees. In Chrome and Edge, the primary difference is also in SVG's. Since they maintain the CSS specified color for currentColor
, if there are different color values depending on the prefers-color-scheme
value then those colors are seen by the user.
Challenges
The most notable challenges with high contrast mode are that box-shadow and background-color compute to none
. This means that any component attempting to show state or other information using either of these properties will not show properly if at all. The difference in the way that SVG's are rendered causes issues with several components and creates significant differences between Firefox and Chrome or Edge browsers.
Opportunities
Few developers or quality assurance engineers test for high contrast issues. There are not currently any good automated tests or tools for setting forced-colors
to active
and looking for visual regressions. This really has to be done by someone manually, at this time. Spending even a small amount of time reviewing your UI for high contrast issues and fixing the highest impact items will go a long way to distinguish your product from others for high contrast users.
Top comments (3)
UPDATE - You CAN now set the browser to emulate high contrast mode in the dev tools. This works in Edge 98 and Chrome 98. Go to dev tools, select "More tools" menu, select "Rendering", then scroll down to "Emulate CSS media feature
forced-colors
", chooseactive
and the browser will re-render the page in a high contrast mode.What do you think about the contrast of gov.uk/
Looks very native and natural (both are good things). I don't see anything obviously broken or difficult to work with.