Хабрахабр

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

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

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

Если автоматический инструмент говорит, что сайт доступен на 100%, это не обязательно так. Lighthouse награждает лучшие сайты зелёным кружочком с цифрой 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>


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

Одного этого достаточно, чтобы устранить абсолютно всех посетителей и пройти тесты Lighthouse, но мы не ищем лёгких путей. hidden визуально скрывает содержимое и удаляет его из дерева доступности (accessibility tree). Итак, добавим 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)
}

Эти правила применяются только в том случае, если включён режим высокой контрастности в 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

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

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

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

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

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

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

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

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

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

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

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

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть