Windows High Contrast Mode, Forced Colors Mode And CSS Custom Properties

About The Author

Eric is a Boston-based designer who helps create straightforward solutions that address a person’s practical, physical, cognitive, and emotional needs. More about Eric ↬

Email Newsletter

Weekly tips on front-end & UX.
Trusted by 176.000 folks.

Quick summary ↬ CSS Custom Properties can be used for far more than just color, and their values update in realtime, both via display mode updates and JavaScript logic. This is powerful stuff. Eric explains how modern CSS is a powerful piece of assistive technology that can thread into it to create flexible, maintainable and adaptive digital experiences.

I’m extremely excited about the upcoming Forced Colors media query. It takes the work done for Windows High Contrast mode and elevates it to an open, cross-browser standard. This means that a person will be able to use whatever browser works best for them to get what they need, instead of being forced to use one specific browser.

What Is Windows High Contrast Mode? What Is Forced Colors Mode?

Windows High Contrast mode, and its successor, Forced Colors mode, are important pieces of assistive technology. These two display modes affect:

  • The operating system installed on a device,
  • The browser is installed on the operating system, and
  • All web content is loaded by that browser.

These display modes prioritize legibility above all else. Ornamentation and decoration are discarded in order to allow content to be displayed clearly.

All content affected by these two modes maps to a color theme. This color theme can be modified by someone to use any combination of colors, to create a suite of colors that works for their specific access needs.

For some, Windows High Contrast/Forced Colors mode represents the last option they have to view content on their device — including web content. This is highly specialized, highly personalized assistive technology, and using it is a very intentional act.

Others may circumstantially benefit from using Windows High Contrast/Forced Colors mode. One of my favorite examples of this is being able to use your laptop in the park, despite the glare of the noonday sun.

Here’s how slots empire bonus codes Magazine looks with Forced Colors activated and set to use the High Contrast #1 theme:

A screenshot of the slots empire bonus codes
 Magazine homepage in Microsoft Edge. Forced Color mode is enabled, showing a stark design using neon colors on a dark background. The featured article is ‘New CSS Features In 2022’, by Michelle Barker. A photo of Michelle accompanies the headline.
You might not think this looks pretty, but it’s hard to argue that it’s difficult to read. (Large preview)

And this is how slots empire bonus codes Magazine looks with Forced Colors activated and set to use the High Contrast White theme:

A screenshot of the slots empire bonus codes
 Magazine homepage in Microsoft Edge. Forced Color mode is enabled, now showing a stark design using mostly blue text on a white background.
(Large preview)

And this is how slots empire bonus codes Magazine looks with Forced Colors activated and set to use a custom theme:

A screenshot of the slots empire bonus codes
 Magazine homepage in Microsoft Edge. Forced Color mode is enabled, now showing a stark design using mostly yellow text on a red background. It looks like a McDonalds.

No, seriously. Forced Colors and Windows High Contrast modes are all about presenting all content — including web content — in a predictable and consistent way.

You only want to make small, surgical tweaks to your content, not create a completely new, bespoke Forced Color mode experience.

Each element’s inherent HTML semantics tell Forced Colors and Windows High Contrast modes how to be displayed. Areas, where semantic HTML isn’t used, are good areas to check — to see if your content holds up.

Forced Colors Mode Keywords

Forced Colors mode — like Windows High Contrast mode — uses a suite of specialized keywords. These keywords assign color to meaning. For example, all inert, regular text will use the same theme color, with this color being mapped to the CanvasText keyword.

The reason keywords are used is because the text color could be any color. Every content type Forced Color mode effect can also, potentially, be any color.

Forced Colors mode has multiple themes, including ones that a person can create for themselves. This lets someone tweak how things look until it works for them.

Sourced from this excellent post, the list of Forced Color keywords is:

Disabled TextGrayText
Selected Text, foregroundHighlightText
Selected Text, backgroundHighlight
Buttons, foregroundButtonText
Buttons, backgroundButtonFace

Here is how these keywords map to the Windows High contrast theme selection interface:

A screenshot from Windows 10 with Windows High contrast settings, showing how color keywords map to the High Contrast #1 theme.
(Large preview)

And here is an example of a custom theme:

A screenshot from Windows 10 with a custom Forced Color mode theme called ‘Custom Theme.’ The theme uses a bright red background, purple buttons, black text, and pale blue hyperlinks.
(Large preview)

This theme might look like the ugliest thing you’ve ever seen, but it’s vital to remember, that this combination of colors might be what lets someone use their device.

CSS Custom Properties

The upgrade of Windows High Contrast mode into Forced Colors mode works really well with another contemporary feature of CSS: Custom Properties.

If you are unfamiliar, Custom Properties are a way to create “variables” in CSS—formalized, encoded values that can be dynamically manipulated.

:root {
  --color-background: #ffffff;
  --color-text: #000000;

@media (prefers-color-scheme: dark) {
  :root {
    --color-background: #000000;
    --color-text: #ffffff;

body {
  background-color: var(--color-background);
  color: var(--color-text);

In this example, I’m creating Custom Properties in the :root selector that will be used to control the background and text color.

I’m initially setting the text color to black and the background color to white, and then updating the Custom Properties to use white text and a black background when dark mode is activated. Invoking the Custom Properties in the body selector is the magic that makes it all happen.

CSS Custom Properties can be used for far more than just color, and their values update in realtime, both via display mode updates and JavaScript logic. This is powerful stuff.

Using Custom Properties With Forced Colors Mode

We’re going to take all this background information and apply it to something concrete: A modal dialog. Do you remember how I said Custom Properties can use more than just color values? We’re going to take advantage of that now.

Unfortunately, the dialog element still has assistive technology compatibility issues, meaning that the most accessible solution is still to use one constructed with the help of ARIA and JavaScript. Kitty Giraudel’s a11y-dialog is a wonderful, flexible resource that I enthusiastically recommend to help you do just that.

Accessibility Workarounds

Since the modal is constructed by using divs, Forced Colors mode does not know it is a modal. It, like Windows High Contrast Mode, does not take ARIA into consideration when determining how color is assigned.

Side-by-side comparison of sample text, link and button. The left side uses a paragraph element, an anchor element, and a button element, while the right side uses ARIA roles of text, link, and button respectively. The left-hand side is picking up Forced Color mode keyword mapping for CanvasText, LinkText, and ButtonText and ButtonFace, while the right side does not.
Windows High Contrast #2 theme showing how semantic HTML maps to Forced Color mode keywords, while ARIA does not. (Large preview)

This is one of the reasons why the Forced Color mode media query and its keywords exist — to tweak content until it works the way someone would expect it to.

Sometimes content isn’t written semantically, and there’s nothing you can do about it. It is no different than using CSS to make tweaks to vendor-supplied code you have no direct control over.

Styling The Modal For Forced Colors Mode

Here’s a CodePen for our modal, before we make our Forced Color mode tweaks:

See the Pen [Modal dialog [forked]]( by Eric Bailey.

See the Pen Modal dialog [forked] by Eric Bailey.

Here’s how it looks without Forced Color mode activated:

A screenshot of a small modal with a title, close button, body content, and a dark background floating above some placeholder text on the page with a light background below it.
(Large preview)

And here is a screenshot of how it looks with Forced Color mode activated:

The same small modal as the previous example, only now with Forced Color mode enabled. All text, including the modal and the background content, is the same color. Both the modal and the page’s background colors are the same. The modal’s border is very thin, and it’s hard to tell where the background content stops and the modal begins.
Windows High Contrast #2 theme. Notice, that all text is using the CanvasText color, and the modal’s close button is using the ButtonText color. (Large preview)

While a blind person using a screen reader may know a modal is present, because of how it is announced, a low vision person using Forced Colors mode may be confused because the modal’s boundaries are not communicated strongly enough visually. This may be further complicated by low vision people who use both Forced Colors mode and a screen reader.

Notice, that even though Forced Colors mode does not know it is a dialog, it does know what a CSS outline declaration is. It takes the very faint, thin light gray border we’re using and colors it with the color value mapped to the CanvasText Forced Color mode keyword.

Also notice, that the modal’s box-shadow has been discarded when Forced Color mode is activated. This, and the outline recoloring are by design.

Remember: Forced Color mode prioritizes legibility above all else, and makes visual updates to honor that.

Making Our Update

Much as how we’re redefining component-level CSS Custom Properties for things like :hover and :active state on the modal close icon, we can redefine for different display modes. Here is a CodePen for our modal after our Forced Color mode tweaks have been made:

See the Pen [Modal dialog with Forced Color mode tweaks [forked]]( by Eric Bailey.

See the Pen Modal dialog with Forced Color mode tweaks [forked] by Eric Bailey.

On line 104 of this CodePen example, we are redefining the --dialog-border-width Custom Property inside a Forced Color mode media query declaration. The reason for doing so is a highly intentional tweak. It takes the thin outline border and makes it dramatically thicker.

 @media (forced-colors: active) {
  --dialog-border-width: var(--size-300);

The reason for this adjustment is that it helps to show the modal’s outer boundary and communicate that it is floating on top of the rest of the page’s content. Forced Color mode removes the modal’s box-shadow, so we cannot rely on that visual affordance in this specialized viewing mode.

Here is a screenshot of it in action:

A screenshot of the same small modal in Forced Color mode, only now the modal’s outer border is a lot thicker. It is easy to see where the background content stops and the modal’s content begins.
(Large preview)


Here’s how to enable contrast themes in Windows. Use macOS or Linux? You’re in luck! There are multiple ways to test for Forced Color support:

  1. Get a Windows craptop and use a tunneling service, such as ngrok. The craptop is also a chance to test your website or web app’s performance — another potential access barrier.
  2. Use an app to load a Virtual Machine with a Windows image provided by Microsoft.
  3. Use a service like Assistiv Labs, which provides a cloud-hosted on-demand Windows Virtual Machine geared towards accessibility testing.
  4. Use Polypane’s media emulation functionality to toggle an emulated Forced Color mode.
  5. Use Microsoft Edge’s DevTools to toggle an emulated Forced Color mode.

I would advise some caution for options four and five, as an emulated experience only uses a single theme, and it’s not representative of the Forced Color mode’s full capabilities.

I particularly like the Assistiv Labs option, because it’s focused on accessibility testing, and it does not heavily tax my laptop the way a local app-run Virtual Machine would.

Wrapping Up

At the surface level, this might seem like a lot of words just to demonstrate how to update a CSS Custom Property. This post’s goal, however, is to introduce you to a powerful piece of assistive technology and show how modern CSS can elegantly thread into it to make flexible, maintainable, and adaptive digital experiences.

Now that you know about Forced Color mode and how it works, why not take some time and audit how your websites and web apps look when it is activated? Some little tweaks might make a huge difference for someone who relies on a Forced Color mode experience to browse the web.

Further Reading

slots empire bonus codes
 Editorial (vf, yk, il)