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.
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.
Share Improve this question edited May 3, 2020 at 7:29 Super Jade 6,3948 gold badges48 silver badges69 bronze badges asked Apr 17, 2020 at 18:00 Mike DoeMike Doe 17.7k11 gold badges73 silver badges95 bronze badges 3- enable them in edge or other browsers? – Mechanic Commented Apr 17, 2020 at 18:16
- There is no way to enable high contrast mode programmatically via JavaScript without using a browser plug in. It would have to be a Windows-only, Internet Explorer-only or pre-Chromium Edge-only solution. – Heretic Monkey Commented Apr 17, 2020 at 18:18
- hey @emix could you clarify, do you want to allow users to toggle your High Contrast styles on and off in the browsers where you cannot determine if they have it switched on (but still let CSS media queries switch them on in IE)? Gave an answer but got downvoted so I may have got the wrong end of the stick! – GrahamTheDev Commented Apr 19, 2020 at 7:15
4 Answers
Reset to default 2Since 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;
}
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
creating a an element with a background color,
appending it to the DOM, and
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.
Here’s the technique, which is really rather simple: create a media query using -ms-high-contrast, in which you place your IE 10 and 11-specific CSS styles. Because -ms-high-contrast is Microsoft-specific (and only available in IE 10+), it will only be parsed in Internet Explorer 10 and greater.
-ms-high-contrast supports two values: none and active. So to target IE10+ regardless of the property’s setting, use this media query:
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
/* IE10+ CSS styles go here */
define the classes you want to add for ms-high-contrast mode.
Once the user clicks the button you have to add the relevant classes to the dom elements dynamically.
Note: This will only work in IE10+ browsers.
Please note if you want to enable high contrast mode from the browser, you can't. This answer is how to apply your High Contrast Styles via a button click while maintaining the media query that doesn't rely on JavaScript to work.
This solution allows you to keep the styles for IE as a media query but also allow them to be toggled manually. It does depend on your high contrast CSS to be located in a separate external file.
What we do is add the style sheet that contains your high contrast CSS rules as an external file.
We give this file a unique ID (#doNotChangeMe
) and the relevant media query media="screen and (-ms-high-contrast: active)"
.
As the above file will only work for IE we are safe to leave it alone.
We then create a function that can also add and remove this style sheet on a button click.
I created a simple toggle function that will query to see if the style sheet exists (without the #doNotChangeMe
id) using a CSS selector.
'link[href*="' + externalFileName + '"]:not(#doNotChangeMe)'
(look for a link with the href
we provided, as long as it doesn't have the relevant ID).
We then see if this CSS file exists in the DOM, if it doesn't we add it again (which will cause no harm assuming your high contrast CSS is the last style sheet in the DOM), otherwise we remove it.
I did try to make this cleaner by changing the media query programatically, however this seemed to have mixed results in browsers and the above seems to work consistently (CORS security policy kicks in if you try to change media.mediaText
for example).
I have linked to the Bootstrap style sheet in the example just for ease of demonstration. You will have to inspect the DOM to see that the high contrast style sheet is not touched by this function (or enable high contrast mode in IE to see that the toggle does not affect anything).
Please note I have not added any indicators to the toggle button to show whether the mode is active, make sure you add relevant WAI-ARIA, button text etc.
//Please note that the below assumes you do not want to interfere with normal media query, if you want people who do have high contrast mode enabled you will need to modify this to remove the ignoreIdOrClass part and instead have a variable containing the state.
var ignoreIdOrClass = '#doNotChangeMe'; //this is the ID of the file that was already in the DOM we do not want to touch
var externalFileName = document.querySelector(ignoreIdOrClass).href; //we grab the URL of the file we want to replicate
function toggleHighContrast() {
var linkNode = document.querySelector('link[href*="' + externalFileName + '"]:not(' + ignoreIdOrClass + ')'); //see if we have added this style sheet to the DOM ourselves, ignore the one with the ID we said to ignore
if(!linkNode){ //our css file copy doesn't exist so create it and add it to the document HEAD
var head = document.head;
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = externalFileName;
head.appendChild(link);
}else{ //our css copy does exist so remove it
linkNode.parentNode.removeChild(linkNode);
}
}
document.getElementById("myBtn").addEventListener("click", toggleHighContrast);
<link id="doNotChangeMe" rel="stylesheet" media="screen and (-ms-high-contrast: active)" href="https://stackpath.bootstrapcdn./bootstrap/4.4.1/css/bootstrap.min.css" />
<div style="padding: 20px;">
<button id="myBtn" class="btn btn-primary btn-lg">Toggle High Contrast</button>
</div>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745653184a4638386.html
评论列表(0条)