3

我想在我的网站上启用高对比度模式,并将所有与可访问性相关的规则放在高对比度媒体查询中:

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

但是,如何以编程方式在 JavaScript 中启用这种模式?我想为我的用户提供一个按钮,让他们根据自己的意愿切换此功能。有没有可能?我做对了吗?也许存在更好的解决方案。

谢谢您的帮助。

4

4 回答 4

2

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

在我看来,您应该简单地编写样式来模拟 IE 的高对比度模式,然后在单击按钮时在文档(可能是正文)上切换一个类。

将新的类和子定义放在 CSS 的底部,这样您就知道它们会覆盖以前的属性。

例如:

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

于 2020-04-17T18:44:18.613 回答
0

请注意,如果您想从浏览器启用高对比度模式,则不能。这个答案是如何通过单击按钮应用您的高对比度样式,同时保持不依赖 JavaScript 工作的媒体查询。

此解决方案允许您将 IE 的样式保留为媒体查询,但也允许手动切换它们。它确实取决于您的高对比度 CSS 是否位于单独的外部文件中。

我们所做的是将包含高对比度 CSS 规则的样式表添加为外部文件。

我们给这个文件一个唯一的 ID( #doNotChangeMe) 和相关的媒体查询media="screen and (-ms-high-contrast: active)"

由于上述文件仅适用于 IE,因此我们可以放心使用。

然后我们创建一个函数,该函数还可以在单​​击按钮时添加和删除此样式表。

#doNotChangeMe我创建了一个简单的切换函数,它将使用 CSS 选择器查询样式表是否存在(没有id)。

'link[href*="' + externalFileName + '"]:not(#doNotChangeMe)'(寻找href我们提供的链接,只要它没有相关的 ID)。

然后我们查看这个 CSS 文件是否存在于 DOM 中,如果不存在,我们再次添加它(假设您的高对比度 CSS 是 DOM 中的最后一个样式表,这不会造成任何伤害),否则我们将其删除。

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

为了便于演示,我已经链接到示例中的 Bootstrap 样式表。您必须检查 DOM 以查看此功能未触及高对比度样式表(或在 IE 中启用高对比度模式以查看切换不会影响任何内容)。

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

于 2020-04-18T08:58:06.750 回答
0

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

对于Windows 10上的大多数浏览器,您可以通过以下方式检测是否启用了高对比度

  1. 创建一个具有背景颜色的元素,

  2. 将其附加到 DOM,并且

  3. 测试以查看背景颜色是否仍然存在:

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有自己的High Contrast 扩展,通常你不需要检测它。但如果你这样做,请检查标签hc上的属性html

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

对于MacOS,您可以检测用户是否启用了反转颜色,如下所示:

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

然后你就可以应用你的样式规则了!


注意:我之前曾疯狂尝试检测其他 MacOS 高对比度设置。答案让我暂时停止尝试,但我希望将来有更好的解决方案。

于 2020-04-17T22:42:28.630 回答
0

下面是一个非常简单的技术:使用 -ms-high-contrast 创建一个媒体查询,在其中放置 IE 10 和 11 特定的 CSS 样式。因为 -ms-high-contrast 是 Microsoft 特定的(并且仅在 IE 10+ 中可用),它只会在 Internet Explorer 10 和更高版本中解析。

-ms-high-contrast 支持两个值:none 和 active。因此,无论属性设置如何,要针对 IE10+,请使用此媒体查询:

@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { /* IE10+ CSS styles go here */

定义要为 ms-high-contrast 模式添加的类。

一旦用户单击按钮,您必须动态地将相关类添加到 dom 元素中。

注意:这仅适用于 IE10+ 浏览器。

于 2020-04-17T18:10:17.023 回答