An Introduction to High Contrast Accessibility
Tags: a11y, frontend, highcontrast, windows
Published: 2022-01-19 21:00:30

---
title: An Introduction to High Contrast Accessibility
published: true
description: An introduction to high contrast mode on Windows and the limitations, challenges and opportunities it presents to web developers.
tags: a11y, FrontEnd, HighContrast, Windows
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/78g5530hlhnd5z7q5d1n.jpg
---
## 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**
1. [Enabling high contrast and customizing it (Windows 10 & 11)](https://support.microsoft.com/en-us/windows/change-color-contrast-in-windows-fedc744c-90ac-69df-aed5-c8a90125e696)
2. [Styling Edge for Windows high contrast mode](https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/)
3. [`forced-colors` media query (Modern browser support)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors)
4. [`-ms-high-contrast` media query (IE11 and Legacy Edge support)](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors)
5. [forced-colors W3C standards](https://www.w3.org/TR/css-color-adjust-1/#forced-colors-properties)

## Rendering native elements and system colors ##

|Default|HC Chrome/Edge|HC Firefox|
|-|-|-|
<img width="500" alt="baseline-default" src="https://user-images.githubusercontent.com/142636/149374315-57db1d2a-0714-49d5-8345-8c2cf1919edc.png">|<img width="500" alt="baseline-hc-chr" src="https://user-images.githubusercontent.com/142636/149374339-1c4b1ee3-d6fe-4b78-9bf6-9d5373813d4b.png">|<img width="500" alt="baseline-hc-ff" src="https://user-images.githubusercontent.com/142636/149374379-85f2fd80-7eaa-4957-a3a1-85df2f59f69f.png">|

## 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.

```css
@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.
<img alt="Setting forced-colors to active in Rendering pane of DevTools" height="180" src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g09tsd9zl3hmymrm7lq7.png">

### 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.