Abnormal programming
Website development
CSS
HTML
June 6

Создаём максимально недоступный сайт с идеальной оценкой Lighthouse

Original author: Manuel Matuzovic
Translation
Встроенный инструмент тестирования Google Lighthouse оценивает доступность (accessibility) сайтов по шкале от 0 до 100. Похвально стремиться к максимальной читаемости контента, но оценка 100 не означает, что сайт идеально доступен. Для доказательства я провёл небольшой эксперимент.

Всегда приятно видеть, как люди хвастаются в твиттере своими оценками Lighthouse: это значит, что они заботятся о качестве.



Lighthouse награждает лучшие сайты зелёным кружочком с цифрой 100, которую вы с гордостью показываете клиентам и друзьям.

Оценка качества кода важна, но ещё важнее правильно её интерпретировать. Если автоматический инструмент говорит, что сайт доступен на 100%, это не обязательно так. Это только значит, что мы заложили основу для тестирования вручную. Для тестов Lighthouse использует библиотеку axe-core со своим набором правил. Она выявляет некоторые плохие практики, но не все. Другие практики не плохи сами по себе, но могут быть вредными, если ими злоупотреблять.

Одним автоматическим тестированием вы не обеспечите хорошее качество. Для доказательства я создал максимально недоступный сайт с идеальной оценкой Lighthouse.

Предыстория


Зак Летерман недавно написал в твиттере:

Бесплатная идея для статьи:

Как построить самый медленный веб-сайт с идеальной оценкой Lighthouse

И ответ Вадима Макеева вдохновил меня на работу.

Было бы интересно почитать! Подкидываю идейку:
<img src=picture.png alt=picture.png>

Я подумал, что это замечательная мысль: не только запутать максимальное количество посетителей сайта, но и получить сверху идеальную оценку Lighthouse.

Отсекаем как можно больше людей


Возьмём за основу эту простую, хорошо доступную страницу.



CodePen: Доступность 100%, шаг 0

Обязательный CSS


Начнём с простого. Я хочу убедиться, что мой идеальный веб-сайт не работает без CSS. Для этого добавляю атрибут hidden в элемент body. Это HTML-эквивалент display: none; в CSS (если хотите почитать о скрытии контента с сохранением доступности, см. «Инклюзивное скрытие» Скотта О'Хары).

HTML


<body hidden>
  ...
</body>


Идеально чистая страница

hidden визуально скрывает содержимое и удаляет его из дерева доступности (accessibility tree). Одного этого достаточно, чтобы устранить абсолютно всех посетителей и пройти тесты Lighthouse, но мы не ищем лёгких путей. Я хочу создать сайт, который совершенно недоступен и технически всё ещё отображает контент. Итак, добавим CSS и вернём контент обратно.

HTML


<head>
  <link rel="stylesheet" href="style.css">
</head>
<body class="loaded" hidden>
  ...
</body>

CSS


.loaded {
  display: block;
}

Мы вернулись к тому, что было раньше, но теперь должен загружаться CSS.

CodePen: доступность 100%, шаг 1

Обязательный JS


Добавим ещё одну зависимость. Класс для отображения контента я теперь добавляю не в HTML, а через JS.

HTML


<head>
  <link rel="stylesheet" href="style.css">
  <script src="script.js"></script>
</head>

<body hidden>
  ...
</body>

JS


  document.querySelector('body').classList.add('loaded');

Здорово! Сайт по-прежнему не изменился, но чтобы отображать хоть какой-то контент, обязательно должны загружаться и правильно работать файлы CSS и JS.

CodePen: доступность 100%, шаг 2

Кажется, пришло время для первого испытания Lighthouse. Скрестим пальцы!



Идеальный результат на сайте c CSS и JS. Это здорово, но мы можем сделать лучше.

К чёрту пользователей со скрин-ридерами


Есть много способов, чтобы помешать работе программ для чтения с экрана. Самый простой и эффективный — использовать атрибут aria-hidden="true". Этот мощный атрибут, его следует применять с осторожностью, потому что он удаляет элементы из дерева доступности. Обычно его применяют для помощи людям со скрин-ридерами, удаляя избыточный или посторонний контент. На нашем сайте прописываем этот атрибут для элемента body.

HTML


<body hidden aria-hidden="true">
  ...
</body>

Теперь люди со скрин-ридерами испытают один из тех «редких» моментов, когда им встречается недоступный сайт.

CodePen: доступность 100%, шаг 3

Отсекаем пользователей с клавиатурами


Пользователи с клавиатурами могут перемещаться по странице, нажимая клавишу Tab для перехода от одного интерактивного элемента к другому. Браузер показывает контур вокруг элементов в фокусе.



Давай избавимся от этого.

CSS


*:focus {
  outline: none !important;
}

Всего тремя строчками CSS мы отсекаем от сайта целую группу людей. Технически, они ещё могут взаимодействовать со страницей: по нажатию Tab по-прежнему происходит переход между интерактивными элементами, просто индикатор фокуса больше не показывается. Поскольку в нашем эксперименте требуется полностью ограничить возможности людей, давайте отключим клавиатуру вообще.

JS


document.addEventListener('keydown', function(e) {
  e.preventDefault();
})

Наше приложение теперь удаляет функциональность по умолчанию всех клавиш.

CodePen: доступность 100%, шаг 4

Время для следующего теста.



Всё ещё идеально.

Ладно, пришло время для грязных трюков.

Эксплоит для режима высокой контрастности


В Windows люди со слабым зрением могут улучшить контраст, включив так называемый режим высокой контрастности.



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

Мы можем таргетировать свойство media специально на этих пользователей.

CSS


@media screen and (-ms-high-contrast: active) {
  /* High contrast styling rules */
  * {
    color: #000000;
  }
}

Эти правила применяются только в том случае, если включён режим высокой контрастности в Windows. К сожалению, мы не знаем, какие цвета использует тема: светлые или тёмные. Установка цвета #000000 для всех элементов может сработать, а может и нет, в зависимости от предпочтений пользователя. Такая вероятность 50% меня не устраивает, но нам повезло: контрастные цвета Windows сопоставляются с ключевыми словами системного цвета CSS. Можно использовать эти ключевые слова и убедиться, что наш текст всегда соответствует цвету любого фона в режиме высокой контрастности. Фоновый цвет в ОС сопоставляется с цветом windows в CSS. Итак, укажем этот цвет для всего текста на странице.

CSS


@media screen and (-ms-high-contrast: active) {
  * {
    color: window !important;
  }
}



О боже. Это так подло. Теперь мне посыпятся предложения на работу от Facebook и Uber.

CodePen: доступность 100%, шаг 5

К чёрту пользователей с мышками


Здесь совсем легко: просто удаляем с экрана курсор.

CSS


*,
*:hover {
  cursor: none;
}

Для пользователя с мышкой свойство cursor: none; делает то же самое, что для пользователя с клавиатурой делает свойство outline: none;. Без курсора сначала трудно ориентироваться, но элементы по-прежнему кликабельны. Давайте улучшим качество нашего приложения, ещё раз обрезав пользователям доступный интерфейс.

CSS


body {
  pointer-events: none;
}

Ну вот, другое дело. После указания pointer-events: none; пользователи больше не могут нажать ни на какой элемент. Это свойство хорошо поддерживается, но чтобы функция работала на как можно большем количестве браузеров, желательно применить принцип прогрессивной деградации.

JS


function removeA11y() {
  if ("pointerEvents" in document.body.style) {
    console.log('pointer-events supported')
    return;
  }

  document.addEventListener('click', function(e) {
    e.preventDefault();
  })
}

removeA11y();

Этот запасной скрипт запускается и удаляет события click из всех элементов, если браузер не поддерживает свойство pointer-events.

CodePen: доступность 100%, шаг 6



Здорово! Сайт по-прежнему совершенно доступен!

К чёрту читаемость


Мы больше не можем использовать мышь или клавиатуру, но всё ещё видим текст на странице. Непорядок.

CSS


body {
  opacity: 0.03;
}

Контент остался на странице, но почти не заметен. Потрясающе!

CodePen: доступность 100%, шаг 7

Эксплоит режима чтения в Safari


Тестируя сайт в разных браузерах, я заметил, что он по-прежнему доступен в Safari в режиме чтения.



Как выяснилось, можно отключить этот режим, если указать минимальный размер шрифта в body.

CSS


body {
  opacity: 0.03;
  font-size: 1px;
}

CodePen: доступность 100%, шаг 8

Долой просмотр исходника


Сайт недоступен для людей с низким и хорошим зрением, пользователей мыши, клавиатуры и скрин-ридеров.

Если опытный пользователь попадёт на такой сайт, в нём может проснуться внутренний хакер и он попытается хакнуть его. Я имею в виду, просмотреть исходный код страницы.

Вишенка на торте недоступности нашего сайта — конвертация текста в HTML-мнемоники. Эти мнемоники (entity) обычно используются для отображения зарезервированных, невидимых символов и тех, которые трудно ввести с помощью стандартной клавиатуры. Мы используем их для обфускации.



CodePen: доступность 100%, шаг 9

И последнее испытание.



Выводы


В статье я вовсе не хотел поиздеваться над системой Lighthouse или её движком axe-core. Я регулярно пользуюсь обоими инструментами и рад, что они есть.

Это статья о нас. Оценки указывают на качество наших приложений и сайтов, но мы не должны слепо доверять этим цифрам. Мы должны понимать, что автоматическое тестирование — только первый шаг.

В следующий раз, когда увидите высокий балл Lighthouse, прочитайте текст рядом с оценкой.

«Данная проверка определяет возможности для улучшения доступности вашего веб-приложения. Автоматическая проверка способна обнаружить только часть проблем, поэтому рекомендуется также провести ручное тестирование».

Мы тестируем и оптимизируем сайты не ради приятного чувства, которое даёт высокая оценка. Мы делаем это для людей: чтобы сайт был доступен как можно большему числу пользователей. В дизайне и программировании мы же не полагаемся полностью на автоматизацию. Вот и в тестировании не следует этого делать.

Спасибо Эрику за корректуру и отзывы.

Ссылки и ресурсы


+136
37.4k 144
Support the author
Comments 41
Top of the day