Новый (и простой) способ скрыть доступный контент
Когда я хочу скрыть доступный контент, я всегда обращаюсь к Фрагмент Джонатана Снука.
.element-invisible {
position: absolute !important;
height: 1px; width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
}
Но вчера я случайно наткнулся на Скотта О’Хара. статья о сокрытии контента. Скотт говорит, что мы хотим скрыть контент только в трех разных контекстах:
- Скрыть это полностью
- Скрыть это визуально
- Скрыть это от программ чтения с экрана
Когда мы говорим, что скрыть контент доступным образом, мы фактически имеем в виду вариант № 2 (скрытие контента визуально, но не от программ чтения с экрана и пользователей клавиатуры).
Тогда у меня появилась идея
Если мы хотим только визуально скрыть элементы, почему бы нам не использовать opacity: 0
? Непрозрачность в любом случае используется для визуального скрытия элементов. Содержимое скрыто с помощью opacity: 0
по-прежнему доступен для чтения с экрана.
.hide-accessibly {
opacity: 0;
}
Я поднял его на ступеньку выше, добавив position: absolute
. Это убирает элемент из потока документов; и позволяет нам стилизовать другие элементы так, как будто скрытого содержимого там нет.
.hide-accessibly {
position: absolute !important;
opacity: 0;
}
Я подумал, что этого достаточно, и спросил об этом Джонатана.
Вот что он ответил:
Он также задавался вопросом, если pointer-events: none
остановит события щелчка клавиатуры (что абсолютно необходимо для программ чтения с экрана и пользователей клавиатуры).
События указателя не должны скрывать, потому что проходят любые события щелчка/касания. Хотя, на самом деле, не уверен, что это нарушает события часов, запускаемые клавиатурой. 🤔
— Снук (@snookca) 24 апреля 2019 г.
Мне было любопытно, поэтому я проверил pointer-events: none
и обнаружил, что он работает с кликами, генерируемыми клавиатурой, кликами, генерируемыми программой чтения с экрана, и кликами, генерируемыми JavaScript.
Вот Codepen, который я использовал для своего теста:
Я сообщил о своих выводах Джонатану, и он сказал, что у нас может быть победитель!
Похоже, тогда у нас может быть победитель!
Фрагмент
Вот фрагмент, если вы хотите использовать этот метод.
.hide-accessibly {
position: absolute !important;
opacity: 0;
pointer-events: none;
}
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Этот метод все еще невероятно нов. Я тестировал его только на последних версиях Firefox, Safari и Chrome. Мне пока не удалось запустить тест в Edge и других браузерах.
Если вы являетесь консультантом по доступности, я был бы очень признателен, если бы вы помогли мне воспользоваться этим фрагментом кода.
В остальном: пока не рекомендую использовать этот фрагмент в продакшене. (Нет, пока я не получу подтверждение от экспертов по доступности).
ОБНОВИТЬ : многие разработчики высказали свое мнение, опасения и эксперименты в Twitter. Я хотел поделиться с вами тем, что я закрепил и узнал.
Вначале обсуждались все три свойства.
Во-первых, поговорим о opacity
.
Проблема с непрозрачностью?
Патрик и Вадим были обеспокоены opacity
потому что он, казалось, сломался в какой-то комбинации браузера и программы чтения с экрана.
Но Джонатан нашел некоторые исследования, которые предполагают, что opacity
хорошо. Далее Патрик провел несколько тестов и согласился, что opacity
хорошо.
Скотт О’Хара также затронул первоначальную проблему с opacity
Вердикт на данный момент:
- Непрозрачность кажется удобной для чтения с экрана!
- Но сейчас это может не работать на ChromeVox. Для подтверждения этого требуются дополнительные тесты.
Далее поговорим о pointer-events
потому что это вторая самая хлопотная вещь.
Pointer-события
Скотт О’Хара отметил, что пользователи iOS Voiceover не смогут инициировать щелчок, если элемент pointer-events: none
. Я проверил то, что сказал Скотт, и обнаружил, что это правда.
Это означает, что мы не можем использовать pointer-events
универсально на всех элементах.
Мой следующий вопрос был: если мы не можем использовать pointer-events
а если мы установим z-index
к -999
? Это предотвратит скрытие элементов, на которые можно щелкнуть, скрытым элементом.
.hide-accessibly {
position: absolute !important;
opacity: 0;
z-index: -999;
}
Ну, Скотт сказал, что мы не должны использовать z-index: -999
на кнопках, потому что визуально скрытые кнопки не будут корректно работать на iOS Voiceover.
Я буду честен. я не понимаю почему z-index: -999
не будет правильно работать с iOS Voiceover, поэтому у меня нет правильного вывода. Я не проверял это.
MacOS Voiceover читает содержимое не в исходном порядке
Скотт и Жоао Белеза Фрейре (@letrastudio, упомянутые выше) указали на заслуживающую внимания ошибку, из-за которой macOS Voiceover считывала контент не в порядке исходного кода.
Я провел свой собственный тест, но ошибка, о которой сообщил Жоао, похоже, не возникает на моем компьютере, хотя мы использовали одно и то же устройство!
Скотт О’Хара поделился дополнительной информацией о том, когда возникает эта ошибка:
Оказывается, куча экспертов (включая Скотта) уже обсуждали эту ошибку macOS Voiceover с 2017 года. Стоит прочитать всю статью. Тема выпуска о проблеме.
Из того, что я читал, кажется, что проблема возникает, когда position: absolute
используется. Когда вы используете position: absolute
и вы возитесь с позиционированием CSS, оно путается с положением кольца фокусировки Voiceover, которое меняет порядок чтения.
Это означает ЛЮБОЕ решение, в котором есть шанс, что macOS Voiceover испортит ЛЮБОЕ решение, содержащее position: absolute
.
😱
И весь этот вопрос касается только озвучки. Мы не рассмотрели, как position: absolute
может сделать его странным для других программ чтения с экрана.
Решение в HTML Boilerplate
Некоторые люди предложили использовать sr-only
фрагмент из HTML5 Boilerplate. Они считали, что это лучший метод, потому что многие эксперты объединились, чтобы создать его.
.sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
white-space: nowrap;
width: 1px;
/* 1 */
}
Однако это то же самое решение, которое вызвало Тема выпуска Я упоминал выше! Эксперты, такие как Скотт О’Хара, работают над этим с 2017 года, и на сегодняшний день не существует решения.
На данный момент лучшее решение было предложено Joe Watkin:
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: auto; /* new - was 1px */
margin: 0; /* new - was -1px */
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap; /* 1 */
}
На момент написания это решение не было официально интегрировано в HTML5 Boilerplate. Примите к сведению.
Опять же, стоит пройти через разговоры в теме темы если вы ботаник в этой области. Это бесценно. (Кстати, я узнал, что aria-label
является игнорируется переводчиками Google и Microsoft! 😱).
Заключительные слова
Хотя решение Джо Уоткина пока кажется лучшим, на самом деле все зависит от него. Каждый метод, который мы обсуждали выше, в статья Джонатанаи везде в интернете есть свои плюсы и минусы.
Как упомянул Скотт, это похоже на ситуацию, когда вы можете выбирать между сеткой, гибкостью и другими методами компоновки. Вы должны выбрать лучший метод в зависимости от ситуации (и ваших знаний о странных причудах).
Есть одна вещь, которую мы можем сделать, чтобы еще больше прояснить ситуацию. И это для того, чтобы собрать плюсы и минусы каждого решения, которое мы знаем до сих пор.
К сожалению, это то, что мне сейчас не по карману. Если вы хотите подойти и поучаствовать в беседе, я уверен, что Джонатан, Скотт и многие другие будут рады поболтать!
Спасибо за чтение. Эта статья изначально была размещена на мой блог. Подписаться на моя рассылка если вы хотите больше статей, которые помогут вам стать лучшим разработчиком внешнего интерфейса.