Доступность (Accessibility)
Эта страница документации не предназначена исключительно для Client-First. Она затрагивает тему доступности внутри Webflow как платформы.
Что такое доступность?
Термин "доступность" (обычно обозначаемый как a11y) не ограничивается только веб-разработкой, он применяется во многих различных аспектах жизни.
Если мы посмотрим определение в Википедии:
"Под доступностью понимается проектирование продуктов, устройств, услуг или среды для людей с ограниченными возможностями".
Применяя это к области веб-разработки, мы понимаем это так:
"Веб доступность (web a11y) означает, что кто угодно в любой момент может использовать ваш сайт".
Почему веб-доступность так важна?
Не поддавайтесь распространенному предположению, что веб-доступность необходима только для людей с тяжелой инвалидностью, например слепотой или ограниченной подвижностью. На самом деле существует больше типов инвалидности, о которых обычно люди не думают:
- Пользователи с постоянно ограниченными возможностями: У пользователя есть тяжелое ограничение, такое как слепота или глухота.
- Пользователи с временно ограниченными возможностями: У пользователя есть физическое или умственное ограничение, которое мешает ему выполнять свои обязанности в течение некоторого промежутка времени.
- Пользователи с условными или ситуативными ограниченными возможностями: Пользователь не может что-то сделать из-за текущей ситуации, в которой он находится. Пример: медленное интернет-соединение, просмотр во время еды...
Об этом руководстве
Это руководство не будет углубляться в основы веб-доступности, так как на эту тему уже написано много качественных статей. Посмотрите A11y Project Checklist и Webflow’s Accessibility Checklist.
Вместо этого, эта страница документации описывает конкретные проблемы доступности, с которыми мы сталкиваемся в Webflow как платформе.
Навигация с помощью клавиатуры
Из-за физических ограничений многие пользователи полагаются на клавиатуру для навигации по нашему сайту. В этом разделе объясняется, как мы можем гарантировать, что весь наш сайт удобен для навигации с помощью клавиатуры.
Основное управление
Клавиша Tab
Клавиша Tab используется для перемещения по странице, фокусируя доступные элементы. Каждый раз, когда пользователь нажимает клавишу Tab, фокус переходит к следующему фокусируемому элементу. Удержание Shift меняет направление.
- Важно убедиться, что все элементы, на которые обычный пользователь мыши нажимал бы на странице, также могут быть сфокусированы с помощью клавиши Tab (см. Использование tabindex).
- Это также подразумевает, что все фокусируемые элементы должны иметь стилизованное состояние фокуса, иначе пользователи не смогут отличить, на каком элементе они в данный момент фокусируются.
Клавиша Enter
При фокусировке на элементе, клавиша Enter должна:
- [Скоро появится решение Finsweet] Активировать ссылки или кнопки. Для нестандартных элементов, таких как div, использующие атрибут role, требуется реализация на JS.
- Отправить форму.
Клавиша Space
При фокусировке на элементе, клавиша Space должна:
- [Скоро появится решение Finsweet] Активировать кнопки.
- Активировать переключаемые состояния, такие как чекбоксы или радио кнопки. Это также имеет отношение к кнопкам, которые переключают некую функциональность, например, открывают аккордеон.
Стрелки
При фокусировке на элементе, клавиши со стрелками должны:
- [Скоро появится решение Finsweet] Перемещаться по сгруппированным дочерним элементам компонента (например, вкладки Tab Links, радио кнопки, переключатели аккордеона, и т.д).
- Изменить его значение (например, для ползунков диапазона или числовых полей).
Клавиша Esc
Клавиша Esc должна позволять пользователю выйти из различных состояний, таких как:
- [Скоро появится решение Finsweet] Закрытие модального окна.
Фокусировка
Все элементы, которые можно нажимать на странице, также должны быть доступны для фокусировки. Стандартные HTML элементы имеют эту функциональность по умолчанию, но иногда мы должны явно указать браузерам на это. В этих случаях это можно сделать, добавив атрибут tabindex. Значение, которое вы задаете для этого атрибута, будет зависеть от желаемого поведения:
- tabindex=”0”: делает элемент доступным для фокусировки при навигации с помощью клавиатуры, следуя естественному порядку элементов на странице.
- tabindex=”X”: где X - любое число больше 0. Это число указывает порядок, по которому элемент должен быть сфокусирован. Пример: элемент с tabindex=”26” будет сфокусирован после элемента с tabindex=”25”.
- tabindex=”-1”: отключает возможность фокусировки на элементе. Это пригодится в некоторых ситуациях, когда у нас есть нативный фокусируемый элемент, который не предоставляет никакой интерактивности.
Программная фокусировка
[Скоро появится решение Finsweet]
Чтобы улучшить UX для навигации с помощью клавиатуры и скринридеров, иногда хорошей идеей будет реализация программной фокусировки на элементе при выполнении определенного условия.
Например, фокусировка на кнопке закрытия сразу после открытия модального окна или перенос фокуса на определенный элемент, который появился на странице.
Однако всегда думайте о UX! В некоторых случаях автоматическая фокусировка на появляющемся на странице элементе не является хорошей идеей, например, при переключении вкладок в компоненте Tabs.
HTML семантика
Использование тегов <button> в Webflow
Основная цель этого тега - сообщить пользователю, что элемент кликабельный и будет вызывать действие на странице. К таким действиям относятся действия типа раскрытия/сворачивания элементов (например, аккордеоны), показ/скрытие элементов (например, бургер-меню или выпадающий список) или пользовательские функции вроде добавления пункта TO-DO в список.
Не путайте теги <button> с компонентом Button в Webflow!
Важно понимать разницу между тегами <button> и <a>:
- <button> активирует действия на странице.
- <a> навигация по странице / веб-сайту
Однако в генерируемом коде Webflow компонент Button - это просто обычная HTML-ссылка (тег <a>) с некоторыми стилями на ней:

К сожалению, использование тега <button> в Webflow на момент написания этого руководства невозможно (если не использовать компонент Embed, что тоже не идеально).
Когда требуется использование тега <button>, мы можем использовать вместо него <div> со следующими условиями:
- У него есть атрибут role=”button”.
- Он может фокусироваться с помощью клавиатуры с атрибутом tabindex.
- [Скоро появится решение Finsweet] На него можно кликнуть с помощью клавиш Enter или Space.
- [Скоро появится решение Finsweet] Если у кнопки есть состояния нажато/не нажато (как у переключателя), она должна иметь атрибут aria-pressed, отражающий текущее состояние.
- [Скоро появится решение Finsweet] Если кнопка управляет раскрытием/сворачиванием другого элемента (например, аккордеона), она должна иметь атрибут aria-expanded, отражающий текущее состояние.
Создание HTML таблиц в Webflow
Элемент <table> не доступен для использования в Webflow.
Однако мы можем создавать таблицы, используя обычные Div (это означает, что скринридер сможет читать содержимое в правильном порядке, следуя по строкам и столбцам), используя ARIA роли, определенные для этой цели. Это показано в этом руководстве в разделе ARIA Roles: role=”table”.
Скрытие элементов на странице
Помимо самого известного стиля display: none, который скрывает элемент из структуры нашей страницы, иногда мы хотим, чтобы элемент был видим только для части пользователей.
Скрытие элементов только для скринридеров
При анализе содержимого нашей страницы, скринридер будет озвучивать пользователю как можно больше информации.
Однако есть некоторые элементы, которые не несут полезной информации, например визуальные элементы, такие как div или svg элементы, использованные только для оформления страницы.
В таких случаях мы хотим, чтобы скринридеры просто пропускали такие элементы и не нарушали логику чтения.
Это можно сделать с помощью атрибута aria-hidden. Подробнее об этом в разделе ARIA ниже.
Скрытие элементов только для обычных пользователей
С другой стороны, иногда мы используем изображения (например, красивый svg в качестве шапки нашей страницы), но все равно хотим, чтобы скринридеры (и поисковые боты!) понимали, о чем идет речь на странице.
Мы можем добиться этого, используя CSS для визуального скрытия контента таким образом, чтобы он все равно был прочитан скринридерами и поисковыми ботами:
.fs-a11y_visually-hidden {
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(0px 0px 99.9% 99.9%);
overflow: hidden;
height: 1px;
width: 1px;
padding: 0;
border: 0;
}
Этот метод используют многие крупные сайты, например, Apple!

ARIA
Документация MDN Web Docs описывает ARIA следующим образом:
"Accessible Rich Internet Applications (ARIA) - это набор атрибутов, которые определяют способы сделать веб-контент и веб-приложения (особенно те, которые разработаны с помощью JavaScript) более доступными для людей с ограниченными возможностями."
При создании статических сайтов без интерактивности обычно достаточно просто использовать правильную HTML семантику.
Но при добавлении пользовательских функций с помощью JavaScript (к ним относятся и Интеракции Webflow!), нам нужно предоставить больше информации для пользователей с ограниченными возможностями, чтобы они могли правильно читать и использовать наш сайт.
Примечание: Встроенные компоненты Webflow, такие как Navbar, Slider, Tabs и др., уже используют правильные атрибуты aria.
ARIA Роли
Элементы, которые предоставляют определенную функциональность на странице (т.е. они выполняют роль), должны быть обозначены так, чтобы скринридеры могли понять контекст действий / ситуаций.
При использовании основных семантических элементов HTML (таких как <button>, <nav>, <a>, <input> и т.д.) атрибуты ролей не нужны, так как и браузер, и скринридеры уже понимают их назначение.
Мы не будем перечислять все доступные роли. Ниже приведены наиболее часто используемые. Полный список можно найти в MDN Docs.
role=”button”
Используется для определения элемента, который не имеет тега <button>, но действует как кнопка.
role=”listbox”
Используется для определения элемента, который содержит список опций для выбора.
role=”option”
Используется для определения элемента, который представляет опцию в списке опций. Обычно комбинируется с атрибутом aria-selected.
role=”table”, role=”rowgroup”, role=”rowheader”, role=”row”, role=”columnheader”
Используется для определения структуры HTML таблицы, где:
- role=”table” соответствует элементу <table>.
- role=”rowgroup” соответствует элементу <tbody>.
- role=”rowheader” соответствует элементу <thead>.
- role=”row” соответствует элементу <tr>.
- role=”columnheader” соответствует элементу <th>.
ARIA Атрибуты
aria-label
То, как элемент распознается скринридером, обычно определяется содержимым этого элемента.
Например, текстовая ссылка:
<a href="https://www.webflow.com">Перейти в Webflow!</a>
Будет произноситься как "Перейти в Webflow!". Но иногда содержимое не объясняет действие, которое будет выполнено, или возможно, там вообще нет никакого содержимого.
В этих случаях использование aria-label позволит нам дать больше поясняющей информации пользователю.
Пример:

aria-labelledby
aria-labelledby, как следует из названия, позволяет нам добавить больше информации об элементе, ссылаясь на другой элемент, который его описывает.
Атрибут используется так:

Где элемент с ID "button-id" имеет некоторое содержимое, которое предоставляет дополнительную информацию для пользователя.
aria-describedby
В дополнение к метке элемента, скринридеры могут озвучить ссылку на элемент в качестве его описания, что помогает пользователю лучше понять его назначение.

Где "description-paragraph" это ID элемента, который содержит описание.
aria-controls
Этот атрибут устанавливает взаимосвязь между элементами. Он определяет элемент или элементы, которые зависят от текущего элемента.
Пример: Кнопка, которая открывает модальное окно при клике на нее, должна иметь:

Где "modal" это ID модального элемента.
aria-expanded
[Решение Finsweet скоро появится]
Есть множество ситуаций, когда пользователю нужно иметь возможность переключать видимость элемента, например, при открытии бургер-меню или модального окна.
Обычно, когда элемент становится видимым на странице, пользователь замечает его сразу. Однако это не относится к слепым людям, которым нужно, чтобы их скринридеры уведомляли их об таких изменениях.
Именно здесь пригодится атрибут aria-expanded, позволяющий нам определить состояние управляемого элемента.
Этот атрибут следует сопоставить с атрибутом aria-controls, чтобы предоставить пользователю более полную информацию об изменениях на странице.
Значение устанавливается на true/false с помощью JavaScript в зависимости от состояния элемента:
aria-expanded=”true”
aria-haspopup
В дополнение к атрибуту aria-expanded, мы можем дополнительно указать, что было открыто с помощью этого атрибута. Он принимает следующие значения:
- aria-haspopup=”menu”, указывает, что всплывающее окно является меню.
- aria-haspopup=”listbox”, указывает, что всплывающее окно является списком.
- aria-haspopup=”tree”, указывает, что всплывающее окно является деревом.
- aria-haspopup=”grid”, указывает, что всплывающее окно является сеткой.
- aria-haspopup=”dialog”, указывает, что всплывающее окно является диалогом.
aria-pressed
[Решение Finsweet скоро появится]
Некоторые элементы требуют визуального подтверждения того, что они были нажаты, например, переключатель, который может принимать состояния "включено" или "выключено". Об изменении состоянии скринридеры могут быть уведомлены с помощью атрибута aria-pressed.
Значение устанавливается на true/false с помощью JavaScript в зависимости от состояния элемента:
aria-expanded=”true”
aria-current
[Решение Finsweet скоро появится]
Используется для определения "текущего" элемента в наборе элементов. У него есть разные применения:
- Страница: Используется как aria-current=”page”, определяет элемент, который имеет текущий URL, где находится пользователь. Обычно устанавливается на ссылки, которые указывают на текущую страницу.
Важно: Состояние Current в Webflow Designer только добавляет CSS-класс w--current к элементу, но не атрибут aria-current. - Местоположение: Используется как aria-current=”location”, определяет элемент, который имеет текущее описание страницы, где находится пользователь. Хороший пример использования - "хлебные крошки", где этот атрибут устанавливается на элемент, указывающий на текущую страницу.
- Дата: Используется как aria-current=”date”, определяет элемент, который имеет текущую дату. Обычно используется в календарях или при выборе даты.
- Шаг: Используется как aria-current=”step”, определяет элемент, который указывает на текущий шаг в многошаговом процессе (например, в многошаговой форме).
aria-selected
[Решение Finsweet скоро появится]
При создании элементов, подразумевающих выбор, например, выпадающего списка опций или комбинированного поля ввода, нам нужно сообщить скринридерам, какой элемент выбран в текущий момент.
Этот атрибут должен быть устанавливаться динамически, указывая на элемент в списке, который в данный момент выбран:

Где "option-2" - это ID выбранного элемента.
aria-hidden
[Решение Finsweet скоро появится]
Как мы видели на примере скрытия элементов от скринридеров, иногда визуальный элемент не дает понимание его смысла пользователю при чтении с помощью скринридера.
Установка атрибута aria-hidden=”true” заставит скринридер пропустить этот элемент при чтении вслух.
Часто используемые компоненты
Создание аккордеонов в Webflow
Триггер:
- [Решение Finsweet скоро будет доступно] В системе USWDS (United States Web Design System - Система веб-дизайна Соединенных Штатов) используются теги <button>, но нам придется полагаться на элементы div с role=”button” и использовать JS для инициирования клика по нажатию Enter или пробела.
- Если используется div, ему нужно присвоить tabindex, чтобы сделать его доступным для навигации с помощью клавиатуры. Также должно быть стилизовано состояние фокуса.
- Используйте aria-controls для обозначения появляющегося контента.
- [Решение Finsweet скоро будет доступно] Используйте aria-expanded для определения состояния складываемого контента.
Контент:
- Не должен быть скрыт по умолчанию. Используйте JS или Интеракции Webflow для его скрытия при загрузке страницы, чтобы убедиться, что люди с отключенным JS (и поисковые роботы!) могут его видеть.
- Используйте aria-labelledby для определения элемента, который его активирует.
Еще интересные вещи, которые мы нашли:
- Когда аккордеонов больше одного, использование стрелочных клавиш должно перемещать фокус между триггерами, использование клавиши Home должно перевести фокус на первый аккордеон, а использование клавиши End - на последний аккордеон. Проверьте здесь.
Плохие примеры реализации доступности
Не использование семантических элементов HTML, когда это возможно
Бывают случаи (например, элементы <button>), когда мы вынуждены искать обходной путь из-за того, что Webflow их не поддерживает.
Но есть и другие случаи, когда использование описания роли не имеет смысла.
Пример: Ссылки
Вот это:
<a href="https://www.google.com">Перейти в Google</a>
Очевидно, предпочтительнее этого:
<div role="link" onclick= "window.location.replace ('https://www.google.com')">Перейти в Google</div>
Хотя обычные пользователи вообще не заметят разницы, пользователи с ограниченными возможностями не смогут перейти к элементу и нажать его с помощью клавиатуры. Также возникнут другие проблемы, такие как SEO индексация ссылки.
Этот пример может показаться слишком простым, но существуют и другие случаи, когда подобное может произойти.
Добавление избыточных атрибутов WAI-ARIA
Семантические элементы (a, form, nav и т.д.) и так будут прочитаны скринридерами. Добавление к ним дополнительного атрибута role заставит скринридер читать его дважды, что может вызвать раздражение.
Пример: Формы
Следующий элемент будет прочитан скринридером как "Форма, Форма":
<form role="form"></form>
Спасибо! На этом пока все!
Мы активно работаем над нашей платформой Attributes, которая даст нам возможность реализовать все, что описано в этом руководстве.
Будьте в курсе новостей и обновлений Finsweet в области веб-доступности (a11y).