Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically enable "-ms-high-contrast" media query?

I'd like to enable high contrast mode on my site and put all accessibility-related rules inside the high contrast media query:

@media screen and (-ms-high-contrast: active) {
  /* All high contrast styling rules */
}

However, how do I enable such mode in JavaScript programmatically? I'd like to have a button for my users to toggle this feature on their will. Is it possible in any way? Am I doing it right? Maybe a better solution exists.

Thank you for your assistance.

like image 819
emix Avatar asked Aug 31 '25 04:08

emix


2 Answers

Since media queries are automatic (based on browser conditions) you need to emulate that block in your CSS but apply and remove it based on a user interaction.

It seems to me that you should simply write the styles to emulate IE's high contrast mode and then toggle a class on the document (probably body) when you click a button.

Put your new class and sub definitions at the bottom of your CSS so you know they'll override previous properties.

For example:

h2 {
  font-size: 14px;
  color: #dddddd;
}
/* overrides a normal h2 when highContrast class is added to the body */
/* use a post processor (LESS/SCSS) to easily nest elements */
body.highContrast h2 {
  font-size: 18px;
  color: #000;
  font-weight: bold;
}
like image 139
Bryce Howitson Avatar answered Sep 02 '25 19:09

Bryce Howitson


As @GrahamRitchie pointed out, while you can’t enable the browser’s high contrast settings via JavaScript, you can usually detect if it’s already enabled.

For most browsers on Windows 10, you can detect whether high contrast is enabled by

  1. creating a an element with a background color,

  2. appending it to the DOM, and

  3. testing to see whether the background color is still there:

isUsingHighContrastMode = () => {
  const testDiv = document.createElement('div');
  testDiv.style.color = 'rgb(50, 50, 50)';
  document.body.appendChild(testDiv);
  const color = document.defaultView!.getComputedStyle(testDiv, null).color;
  document.body.removeChild(testDiv);
  return color !== 'rgb(50, 50, 50)' ? true : false;
}

Chrome has its own High Contrast extension, and usually you don't need to detect it. But if you do, check for the hc attribute on the html tag:

const htmlTag = document.getElementsByTagName(
    'html'
  )[0];
const isUsingChromeHighContrastExtension: boolean =
    htmlTag.getAttribute('hc') !== null;

For MacOS, you can detect if the user has Invert colors enabled like this:

isUsingMacInvertedColors = () => {
      const mediaQueryList = window.matchMedia('(inverted-colors: inverted)');
      return mediaQueryList.matches;
}

Then you can apply your styling rules!


Note: I previously tried like crazy to detect other MacOS high contrast settings. The answers led me to stop trying for awhile, though I hope for a better solution in the future.

like image 20
Super Jade Avatar answered Sep 02 '25 18:09

Super Jade