简体   繁体   English

如何以编程方式启用“-ms-high-contrast”媒体查询?

[英]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?但是,如何以编程方式在 JavaScript 中启用这种模式? 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.谢谢您的帮助。

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.由于媒体查询是自动的(基于浏览器条件),您需要在 CSS 中模拟该块,但根据用户交互应用和删除它。

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.在我看来,您应该简单地编写 styles 来模拟 IE 的高对比度模式,然后在单击按钮时在文档(可能是正文)上切换 class。

Put your new class and sub definitions at the bottom of your CSS so you know they'll override previous properties.将新的 class 和子定义放在 CSS 的底部,这样您就知道它们会覆盖以前的属性。

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; }

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.这是一个非常简单的技术:使用 -ms-high-contrast 创建一个媒体查询,在其中放置特定于 IE 10 和 11 的 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 是 Microsoft 特定的(并且仅在 IE 10+ 中可用),所以它只会在 Internet Explorer 10 及更高版本中解析。

-ms-high-contrast supports two values: none and active. -ms-high-contrast 支持两个值:none 和 active。 So to target IE10+ regardless of the property's setting, use this media query:因此,无论属性设置如何,要针对 IE10+,请使用此媒体查询:

@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.定义要为 ms-high-contrast 模式添加的类。

Once the user clicks the button you have to add the relevant classes to the dom elements dynamically.一旦用户单击按钮,您必须动态地将相关类添加到 dom 元素中。

Note: This will only work in IE10+ browsers.注意:这仅适用于 IE10+ 浏览器。

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.正如@GrahamRitchie 指出的那样,虽然您无法通过 JavaScript 启用浏览器的高对比度设置,但您通常可以检测它是否已启用。

For most browsers on Windows 10 , you can detect whether high contrast is enabled by对于Windows 10上的大多数浏览器,您可以通过以下方式检测是否启用了高对比度

  1. creating a an element with a background color,创建一个具有背景颜色的元素,

  2. appending it to the DOM, and将其附加到 DOM,并且

  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. Chrome有自己的High Contrast 扩展,通常你不需要检测它。 But if you do, check for the hc attribute on the html tag :但如果这样做,请检查html标签上的hc属性

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:对于MacOS ,您可以检测用户是否启用了 Invert colors ,如下所示:

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 .注意:我之前曾疯狂尝试检测其他 MacOS 高对比度设置 The answers led me to stop trying for awhile, though I hope for a better solution in the future.答案让我暂时停止尝试,但我希望将来有更好的解决方案。

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.这个答案是如何通过单击按钮应用您的高对比度 Styles,同时保持不依赖 JavaScript 工作的媒体查询。

This solution allows you to keep the styles for IE as a media query but also allow them to be toggled manually.此解决方案允许您将 IE 的 styles 保留为媒体查询,但也允许手动切换它们。 It does depend on your high contrast CSS to be located in a separate external file.它确实取决于您的高对比度 CSS 是否位于单独的外部文件中。

What we do is add the style sheet that contains your high contrast CSS rules as an external file.我们所做的是将包含您的高对比度 CSS 规则的样式表添加为外部文件。

We give this file a unique ID ( #doNotChangeMe ) and the relevant media query media="screen and (-ms-high-contrast: active)" .我们给这个文件一个唯一的 ID ( #doNotChangeMe ) 和相关的媒体查询media="screen and (-ms-high-contrast: active)"

As the above file will only work for IE we are safe to leave it alone.由于上述文件仅适用于 IE,因此我们可以放心使用。

We then create a function that can also add and remove this style sheet on a button click.然后我们创建一个 function,它还可以在单击按钮时添加和删除此样式表。

I created a simple toggle function that will query to see if the style sheet exists (without the #doNotChangeMe id) using a CSS selector.我创建了一个简单的切换 function,它将使用 CSS 选择器查询样式表是否存在(没有#doNotChangeMe id)。

'link[href*="' + externalFileName + '"]:not(#doNotChangeMe)' (look for a link with the href we provided, as long as it doesn't have the relevant ID). 'link[href*="' + externalFileName + '"]:not(#doNotChangeMe)' (查找与我们提供的href的链接,只要它没有相关 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.然后我们查看这个 CSS 文件是否存在于 DOM 中,如果不存在,我们再次添加它(假设您的高对比度 CSS 是 DOM 中的最后一个样式表,这不会造成任何伤害),否则我们将其删除。

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).我确实尝试通过以编程方式更改媒体查询来使这个更清洁,但是这似乎在浏览器中产生了混合结果,并且上面似乎始终如一地工作(例如,如果您尝试更改media.mediaText ,CORS 安全策略就会启动)。

I have linked to the Bootstrap style sheet in the example just for ease of demonstration.为了便于演示,我已经链接到示例中的 Bootstrap 样式表。 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).您必须检查 DOM 以查看此 function 未触及高对比度样式表(或在 IE 中启用高对比度模式以查看切换不会影响任何内容)。

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.请注意,我没有在切换按钮上添加任何指示器来显示模式是否处于活动状态,请确保添加相关的 WAI-ARIA、按钮文本等。

 //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.com/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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM