Как программно включить медиа-запрос "-ms-high-контраст"? - PullRequest
2 голосов
/ 17 апреля 2020

Я бы хотел включить высококонтрастный режим на своем сайте и поместить все правила, связанные с доступностью, в высококонтрастный медиа-запрос:

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

Однако как мне включить такой режим в JavaScript программно? Я бы хотел, чтобы мои пользователи включали эту функцию по своему желанию. Это возможно каким-либо образом? Я делаю это правильно? Возможно, существует лучшее решение.

Спасибо за вашу помощь.

Ответы [ 4 ]

2 голосов
/ 17 апреля 2020

Поскольку медиазапросы автоматизированы c (в зависимости от условий браузера), вам нужно эмулировать этот блок в вашем 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;
}
0 голосов
/ 18 апреля 2020

Обратите внимание , если вы хотите включить высококонтрастный режим из браузера, вы не можете. Этот ответ заключается в том, как применить стили с высокой контрастностью одним нажатием кнопки, одновременно поддерживая медиазапрос, который не работает на JavaScript.

Это решение позволяет сохранить стили для IE как медиа-запрос, но также позволяет переключать их вручную. Это зависит от того, находится ли ваш высококонтрастный CSS в отдельном внешнем файле.

Мы добавляем таблицу стилей, содержащую ваши высококонтрастные правила CSS, в качестве внешнего файла.

Мы даем этому файлу уникальный идентификатор (#doNotChangeMe) и соответствующий медиазапрос media="screen and (-ms-high-contrast: active)".

Поскольку указанный выше файл будет работать только для IE, мы можем оставить его в покое.

Затем мы создаем функцию, которая также может добавлять и удалять эту таблицу стилей одним нажатием кнопки.

Я создал простую функцию переключения, которая будет запрашивать, существует ли таблица стилей (без #doNotChangeMe id) с помощью селектора CSS.

'link[href*="' + externalFileName + '"]:not(#doNotChangeMe)' (ищите ссылку с предоставленным нами href, если у него нет соответствующего идентификатора).

Затем мы видим, существует ли этот файл CSS в DOM, если мы не добавим его снова (это не повредит, если ваш высокий контраст CSS - последняя таблица стилей в DOM), в противном случае мы удалите его.

Я пытался сделать это чище с помощью Changi При использовании медиазапроса программно, однако в браузерах это показало неоднозначные результаты, и приведенное выше работает согласованно (например, политика безопасности CORS срабатывает, если вы пытаетесь изменить media.mediaText).

Я связался с таблица стилей Bootstrap в примере только для простоты демонстрации. Вам нужно будет проверить DOM, чтобы увидеть, что эта функция не затрагивает высококонтрастную таблицу стилей (или включить режим высокой контрастности в IE, чтобы убедиться, что переключение не влияет ни на что).

Обратите внимание Я не добавил никаких индикаторов к кнопке переключения, чтобы показать, активен ли режим, убедитесь, что вы добавили соответствующий WAI-ARIA, текст кнопки и т. Д. c.

//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>
0 голосов
/ 18 апреля 2020

Как отметил @ GrahamRitch ie, хотя вы не можете включить высококонтрастные настройки браузера с помощью 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 имеет свой собственный Высококонтрастное расширение , и обычно вам не нужно его обнаруживать. Но если вы это сделаете, проверьте атрибут hc в теге html :

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


Для MacOS , вы можете определить, имеет ли пользователь Инвертированные цвета , например:

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


Затем вы можете применить свои правила стиля!


Примечание. Ранее я пытался как сумасшедший, чтобы обнаружил другие настройки MacOS с высокой контрастностью . Ответы заставили меня на некоторое время перестать пытаться, хотя я надеюсь на лучшее решение в будущем.

0 голосов
/ 17 апреля 2020

Вот техника, которая на самом деле довольно проста: создайте медиа-запрос, используя -ms-high-контраст, в который вы помещаете ваши IE 10 и 11-специфичные c CSS стили. Поскольку -ms-high-контраст является спецификацией Microsoft c (и доступна только в IE 10+), он будет анализироваться только в Inte rnet Explorer 10 и более поздних версиях.

-ms- высококонтрастный поддерживает два значения: нет и активное. Поэтому для нацеливания на IE10 + независимо от настройки свойства используйте этот медиазапрос:

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

, чтобы определить классы, которые вы хотите добавить для режима высокой контрастности мс.

Когда пользователь нажимает кнопку, вы должны динамически добавлять соответствующие классы в элементы dom.

Примечание. Это будет работать только в браузерах IE10 +.

...