Foot notes из докладов

Про модальные окна

  • атрибут inert делает блок "недоступным" - его можно повесить на основной landmark, пока открыто модальное окно
  • focus-lock частично делает обратное - фиксирует фокус на конкретном DOM-узле

Из релиз-трекера сафари:

* https://webkit.org/blog/8332/release-notes-for-safari-technology-preview-59/

(Можно читать про поддержку VoiceOver)

Систематизация

https://www.24a11y.com/2017/writing-automated-tests-accessibility/

In a basic sense, the first accessibility testing tool I would recommend is the keyboard. Tab through the page to see if you can reach and operate interactive UI controls without using the mouse.

It’s important to write multiple tests for each state of the page, including opening modal windows, menus, and other hidden regions that will otherwise be skipped by the API. This makes sure that you’re testing each state of the page for accessibility, since an automated tool can’t guess your intent when things are hidden with display: none or dynamically injected on open.

автоматизация

https://github.com/theintern/intern-a11y

'check accessibility': function () {
	return this.remote
		.get('page.html')
		.then(aXe.createChecker());
}

https://24ways.org/2017/automating-your-accessibility-tests/

Многие очень уж хвалят Pa11y

Падающие bluebird-промисы - повод валить тесты!

process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at:', p, 'reason:', reason);
  process.exit(1);
});
process.on('uncaughtException', (err) => {
  console.log('Caught exception: ${err}n');
  process.exit(1);
});

https://www.24a11y.com/2017/writing-automated-tests-accessibility/

Deque’s axe-core library. It’s incorporated into Lighthouse for Google Chrome, Sonarwhal by Microsoft’s Edge team, Ember A11y Testing, Storybook, Intern, Protractor, DAISY, and more.

Как не умереть от позора

const test = pa11y({
  ignore: [
    'notice',
    'warning'
  ],
...
});
const test = pa11y({
  ....
  hideElements: '#ratings, #js-bigsearch',
  ...
});

const ignoreErrors: string[] = [
  '<img src="https://books.google.com/intl/en/googlebooks/images/gbs_preview_button1.gif" border="0" style="cursor: pointer;" class="lightbox-is-image">',
  '<script type="text/javascript" id="">var USI_orderID=google_tag_mana...</script>',
  '<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=123456789012345&ev=PageView&noscript=1">'
  ];
  const filterResult = result => {
    if (ignoreErrors.indexOf(result.context) > -1) {
      return false;
    }
    return true;
  };

Меню

http://adrianroselli.com/2017/10/dont-use-aria-menu-roles-for-site-nav.html

Somehow many developers have come to the conclusion that a web page is inaccessible unless it uses ARIA. This is a combination of patterns that do not use semantic HTML, a misunderstanding of ARIA, and not having practical experience with assistive technology.

https://inclusive-components.design/menus-menu-buttons/

  • навигация на сайте – не menu, не haspopup, ЗА ИСКЛЮЧЕНИЕМ меню, открывающихся по кнопке (tinkoff.ru как раз тот случай) (и такие меню лучше всего работают на тач-устройствах), но теряется семантика ссылок, так как menuitem переопределяет нативную, в то время как nav со списком внутри дает элементам <li> роль implicit link
  • Information architecture is a big part of inclusion. A badly organized site can be as technically compliant as you like, but will still alienate lots of users — especially those with cognitive impairments or those who are pressed for time.

https://codepen.io/grayghostvisuals/pen/ltjDa

меню реагирует на нажатия клавиш, соответствующих первым буквам лейблов кнопок меню (аналогично виндовым), можно улучшить - воспринимать ввод с таймаутом в ~200мс на клавишу (не очень полезно для людей с проблемами координации, но остальным ок)

https://www.w3.org/WAI/tutorials/menus/flyout/#flyoutnavkbfixed

хорошие примеры меню с выпадашкой для навигации (особенно хорошо с кнопкой для раскрытия с клавиатуры отдельно от ховера

Оповещение пользователя о событиях SPA

combine aria-live="..." with roles:

role=status — текущее состояние (например, незаполненные поля формы)

role=alert — например, дублирование обычных алертов

aria-relevant: The aria-relevant=[LIST_OF_CHANGES] is used to set what types of changes are relevant to a live region. The possible settings are: one or more of: additionsremovalstextall. The default setting is: additions text.