- PVSM.RU - https://www.pvsm.ru -

Кнопки «Закрыть»: паттерны и антипаттерны

На модальных окнах, на рекламных объявлениях, на других подобных всплывающих элементах веб-страниц часто можно найти кнопку «Закрыть» с соответствующим символом. Эти кнопки позволяют пользователям (по крайней мере — некоторым из них) закрывать окна. Возможность щёлкнуть по кнопке «Закрыть» часто доступна только тем посетителям веб-страниц, у которых есть мышь. Дело в том, что большинство реализаций подобных кнопок далеко не идеально. В материале, перевод которого мы сегодня публикуем, будет рассмотрено 11 проблемных паттернов, которые используются при создании кнопок «Закрыть», а также — способы решения проблем этих паттернов. Здесь же речь пойдёт и об удачных способах создания кнопок «Закрыть».

Кнопки «Закрыть»: паттерны и антипаттерны - 1 [1]

Неудачные паттерны

▍Паттерн №1: элемент div и фоновое изображение

Взглянем на HTML-код, используемый для создания кнопки «Закрыть»:

<div class="close"></div>

Вот стили:

.close::after {
  background: url("close.png");
  content: "";
}

Проблемы и их решение

Ниже приведён список проблем, которые характерны для данного варианта реализации кнопки «Закрыть». Зная об этих проблемах, можно наметить пути их решения.

  1. Элемент <div> — это элемент, которым пользуются в крайнем случае, тогда, кода для решения некоей задачи просто нет другого, более подходящего элемента. Использование <div> вместо более подходящих элементов ведёт к плохой доступности проекта.
  2. Событие click элемента <div> вызывается только в том случае, если по нему щёлкают мышью. А, например, такое же событие элемента <button> вызывается и по щелчку мыши, и по нажатию клавиш Enter и Пробел на клавиатуре.
  3. Элемент <div> не поддерживает получение фокуса с клавиатуры.
  4. Здесь нет текстовой альтернативы фоновому изображению.
  5. Средства для чтения с экрана не «озвучивают» этот элемент.

▍Паттерн №2: элемент div и иконка

Вот разметка:

<div class="close">
  ✕
</div>

Проблемы и их решение

  1. Значок ✕ не является чем-то таким, что можно напрямую соотнести с командой «Закрыть». Этот значок используется для записи математических выражений, в которых одно число умножается на другое (вроде 2✕2). Не стоит использовать его для оформления кнопки «Закрыть».
  2. О минусах использования элемента <div> при оформлении кнопок «Закрыть» читайте в разделе «Паттерн №1».
  3. Средства для чтения с экрана «озвучат» этот значок, использовав какое-нибудь слово, имеющее отношение к умножению (вроде «multiplication x» или «times»).

▍Паттерн №3: иконки из Font Awesome

Вот HTML-разметка:

<div class="close">
  <i class="fas fa-times"></i>
</div>

Вот CSS-код:

.fa-times::before {
  content: 'f00d';
}

Проблемы и их решение

  1. Средства для чтения с экрана могут озвучить содержимое, сгенерированное средствами CSS.
  2. В документации [2] к Font Awesome рекомендуется семантически скрывать иконки, например, пользуясь атрибутом aria-hidden=«true» элемента <i>.
  3. Font Awesome добавляет на страницу Unicode-содержимое с помощью псевдоэлемента ::before. Ассистивные технологии могут озвучить Unicode-эквивалент соответствующей иконки, что в данном примере приведёт к сообщению о том, что тут имеется символ умножения («times»). Дело в том, что fa-times [3] — это не символ-крестик, а знак умножения. Обратите внимание на то, что Talkback и VoiceOver при обработке подобного кода вообще ничего не «говорят».
  4. Элемент <i> представляет собой фрагмент текста, который, при использовании средств для чтения с экрана, должен озвучиваться другим голосом или с другой интонацией. То есть это — фрагмент, который система должна «прочитать» не так, как обычный текст. Если всё, что нужно — это текст, набранный курсивом, рекомендуется использовать CSS-стиль font-style: italic;.
  5. О недостатках элемента <div> читайте в разделе «Паттерн №1».

▍Паттерн №4: ссылка «Закрыть»

Вот HTML-код:

<a href="#" class="close">
</a>

Вот стили:

a::after {
  font-size: 28px;
  display: block;
  content: "×";
}

Проблемы и их решение

  1. Если у элемента <a> есть атрибут href, он представляет собой ссылку на некий ресурс — вроде другой веб-страницы или PDF-документа.
  2. Цель элемента из этого примера заключается в вызове на той же самой странице действия, выполняемого средствами JavaScript. В такой ситуации лучше подойдёт элемент <button>, атрибут type которого установлен в значение button. Дело в том, что такой элемент, по умолчанию, не выполняет никаких действий. Он создан специально для того, чтобы вызывать выполнение каких-то действий в ответ на события пользовательского ввода.
  3. Если вы не уверены в том, какой именно элемент использовать, <a> или <button>, посмотрите это [4] видео.
  4. Средства для чтения с экрана могут «прочитать» то, что будет сгенерировано с помощью CSS. Значок, используемый в этом примере, как и в предыдущих примерах, это не значок «закрыть», а значок, символизирующий умножение. Его не стоит использовать для оформления кнопок «Закрыть».
  5. Средства для чтения с экрана, разбирая этот код, могут сообщить о значке умножения и о ссылке, но не о кнопке «Закрыть».

▍Паттерн №5: ссылка «Закрыть» с текстом

Вот HTML-код этого паттерна:

<a href="#" class="close">
  Close
</a>

Вот CSS-код:

.close::before {
  content: "e028";
}

Проблемы и их решение

  1. Это, на самом деле, не так уж и плохо, но тут, всё же используется ссылка, а не кнопка.
  2. Почитайте то, о чём говорится в разделе «Паттерн №4» относительно элементов <a> и содержимого, генерируемого средствами CSS.
  3. Средства для чтения с экрана могут «озвучить» подобный элемент как «link, times close».

▍Паттерн №6: ссылка «Закрыть» без атрибута href

Вот разметка:

<a class="close" onclick="close()">×</a>

Проблемы и их решение

  1. Перед нами ещё один пример, который нельзя признать очень уж плохим, но тут у ссылки нет атрибута href, и это, опять же, ссылка, а не кнопка.
  2. Если у элемента <a> нет атрибута href, это значит, что элемент представляет собой местозаполнитель элемента, куда могла бы быть вставлена реальная ссылка.
  3. Если вы обрабатываете событие щелчка на ссылке-местозаполнителе, то вам, возможно, стоит использовать не такую ссылку, а ссылку с атрибутом href, или элемент <button>. Это зависит от того, что именно происходит при щелчке по подобному элементу.
  4. Ссылки-местозаполнители не могут получать фокус.
  5. Если вы не знаете точно о том, что именно вам нужно, элемент <a> или <button>, обратитесь к этому [4] видео.
  6. Средства для чтения с экрана могут «прочитать» этот элемент как «times, clickable».

▍Паттерн №7: ссылка-местозаполнитель и элемент img

Вот HTML-код этого паттерна:

<a onclick="close();">
   <img src="close.png">
 </a>

Проблемы и их решение

  1. Тут нет текстовой альтернативы изображению.
  2. Об особенностях ссылок-местозаполнителей читайте в разделе «Паттерн №6».
  3. Средства для чтения с экрана могут «прочитать» в такой ситуации имя файла, например, выдать что-то вроде «close.png, image».

▍Паттерн №8: радиокнопка

Вот HTML-код:

<label class="close" for="close">
   <svg> … </svg>
 </label>
 <input id="close" type="radio">

Вот применяемый здесь стиль:

[type="radio"] {
  display: none;
}

Проблемы и их решение

  1. Когда люди, которые продвигают идеи доступности контента, говорят о том, что нужно просто использовать кнопки [5], они имеют в виду элемент <button>, а не радиокнопки.
  2. Радиокнопки используются в группах, описывающих наборы взаимосвязанных опций.
  3. У SVG-изображения нет текстовой альтернативы. Вот [6] хорошая статья о доступности SVG-изображений.
  4. Средства для чтения с экрана могут никак не «озвучить» такой элемент.

▍Паттерн №9: кнопка с иконкой

Как обычно, сначала рассмотрим разметку:

<button class="close" type="button">
  ×
</button>

Проблемы и их решение

  1. Значок ✕, с которым мы уже встречались, это не символ закрытия чего-либо. Это знак, символизирующий умножение. Не стоит использовать его для оформления кнопки «Закрыть».
  2. Средства для чтения с экрана могут «прочитать» эту кнопку как «times, button».

▍Паттерн №10: кнопка с SVG-изображением

HTML-код:

<button class="close">
  <svg> … </svg>
</button>

Проблемы и их решение

  1. Здесь нет текстовой альтернативы SVG-изображению. О доступности таких изображений читайте здесь [6].
  2. Средства для чтения с экрана могут сообщить о том, что тут имеется «button», не «сказав» больше ничего.

▍Паттерн №11: старый добрый символ X

Вот HTML-код, реализующий этот паттерн:

<div role="button" tabindex="0">X</div>

Проблемы и их решение

  1. Учитывая то, что существует элемент <button>, в явной настройке семантики кнопки с использованием атрибута role необходимости нет.
  2. Если пользоваться элементом <button>, не нужно применять атрибут tabindex. HTML-кнопки, по умолчанию, рассчитаны на возможность получения ими фокуса ввода.
  3. О минусах <div> читайте в разделе «Паттерн №1».
  4. Символ, представляющий букву X, это не иконка для закрытия чего-либо.
  5. Средства для чтения с экрана могут «озвучить» этот элемент как «X».

Вот что по этому поводу сказал [7] Макс Бок: «Использовать символ x для кнопок закрытия — это как сыпать соль в кофе только из-за того, что она выглядит так же, как сахар».

Вот [8] CodePen-проект, в котором собраны неудачные паттерны создания кнопок «Закрыть»

Альтернативы неудачным паттернам

▍Решение №1: кнопка с видимым текстом без иконки

Вот разметка, применяема в этом решении:

<button type="button">
  Close
</button>

Особенности

  1. Здесь используется только текст. Такую кнопку просто реализовать, её назначение понятно пользователям.
  2. Средства для чтения с экрана могут «озвучить» такую кнопку как «Close, button».

▍Решение №2: кнопка с видимым текстом и с иконкой, скрытой от ассистивных технологий

HTML-код:

<button type="button">
  Close
  <span aria-hidden="true">×</span>
</button>

Особенности

  1. Если вам и правда нужно пользоваться иконкой, которая, в обычных условиях, используется как символ умножения, её стоит скрыть от средств для чтения с экрана, поместив в элемент <span> с атрибутом aria-hidden=«true».
  2. Средства для чтения с экрана могут сообщить о том, что это «Close, button».

▍Решение №3: кнопка со скрытым текстом и со значком, который видим на экране, но скрыт от ассистивных технологий

Вот HTML-код этого решения:

<button type="button">
  <span class="sr-only">Close</span>
  <span aria-hidden="true">×</span>
</button>

Вот стиль:

.sr-only {
  position: absolute;
  white-space: nowrap;
  width: 1px;
  height: 1px;
  overflow: hidden;
  border: 0;
  padding: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  margin: -1px;
}

Особенности

  1. К сожалению, нет стандартного способа скрытия элементов, при использовании которого они не видны, но остаются доступными для ассистивных технологий. Эта задача решается здесь с помощью стиля класса .sr-only.
  2. Средства для чтения с экрана могут «озвучить» эту кнопку как «Close, button».

▍Решение №4: ещё один вариант кнопки со скрытым текстом и со значком, который видим на экране, но скрыт от ассистивных технологий

Вот HTML-разметка:

<button type="button" aria-label="Close">
  <span aria-hidden="true">×</span>
</button>

Особенности

  1. Если вам не хочется выводить текст — назначьте иконке или SVG-изображению текстовую альтернативу, воспользовавшись атрибутом кнопки aria-label.
  2. Средства для чтения с экрана могут сообщить о том, что перед нами «Close, button».

▍Решение №5: использование Font Awesome

Вот, ради полноты изложения, удачный пример кнопки «Закрыть», при создании которой используется Font Awesome:

<button type="button" class="close" aria-label="Close">
  <span class="fa fa-times" aria-hidden="true"></span>
</button>

▍Общие замечания

Иногда имеет смысл использовать метки с более подробными описаниями действий, вроде «Закрыть окно», или «Закрыть галерею», или «Закрыть рекламу».

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

Здесь [9] можно найти примеры реализации удачных паттернов кнопок «Закрыть».

Как сделаны кнопки «Закрыть», которые используются в ваших проектах?

Автор: ru_vds

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka/353862

Ссылки в тексте:

[1] Image: https://habr.com/ru/company/ruvds/blog/505758/

[2] документации: https://fontawesome.com/v4.7.0/accessibility/

[3] fa-times: https://fontawesome.com/icons/times

[4] это: https://www.youtube.com/watch?v=8XjwDq9zG4I

[5] кнопки: https://www.youtube.com/watch?v=CZGqnp06DnI

[6] Вот: https://www.deque.com/blog/creating-accessible-svgs/

[7] сказал: https://twitter.com/mxbck/status/1187446513284325376

[8] Вот: https://codepen.io/matuzo/pen/qBOvagg?editors=1100

[9] Здесь: https://codepen.io/matuzo/pen/zYvbmvm?editors=1100

[10] Источник: https://habr.com/ru/post/505758/?utm_source=habrahabr&utm_medium=rss&utm_campaign=505758