Тултип (tooltip) — это контекстная подсказка, которая появляется рядом с элементом интерфейса и содержит краткое пояснение его назначения. В настольных интерфейсах подсказки традиционно отображаются при наведении курсора мыши. В мобильной среде этот механизм отсутствует: сенсорные экраны не поддерживают состояние hover, а взаимодействие происходит через касание.
Из-за этого обычные реализации тултипов оказываются неприменимыми. Попытка использовать те же подходы приводит к проблемам доступности:
Библиотека ally.js предоставляет набор инструментов для корректной работы с фокусом, интерактивными элементами и доступностью интерфейсов. При разработке мобильных тултипов она помогает управлять фокусом, контролировать доступность элементов и корректно обрабатывать взаимодействие без hover-событий.
Мобильный тултип должен строиться вокруг нескольких ключевых принципов:
Типичная структура включает:
<button id="help-button" aria-describedby="tooltip-help">
?
</button>
<div id="tooltip-help" role="tooltip" hidden>
Дополнительная информация о функции
</div>
В этом примере:
aria-describedby связывает кнопку и подсказку;role="tooltip" сообщает вспомогательным технологиям о
назначении элемента;hidden управляет видимостью.Важная задача — определить, может ли элемент получать фокус и участвовать во взаимодействии. Модуль ally.is.focusable позволяет определить, доступен ли элемент для фокусировки.
import ally from 'ally.js';
const tooltip = document.getElementById('tooltip-help');
if (ally.is.focusable(tooltip)) {
console.log('Элемент может получать фокус');
}
Это особенно полезно в мобильных интерфейсах, где элементы часто динамически появляются и исчезают.
Поскольку hover недоступен, подсказка активируется через событие
touchstart или click.
const button = document.getElementById('help-button');
const tooltip = document.getElementById('tooltip-help');
button.addEventListener('click', () => {
tooltip.hidden = false;
});
Однако подобная реализация не решает проблему управления фокусом. После появления подсказки фокус может оставаться на исходном элементе, что создаёт проблемы для пользователей экранных считывателей.
Модуль ally.element.focus позволяет программно перемещать фокус.
ally.element.focus(tooltip);
Пример полной логики открытия:
button.addEventListener('click', () => {
tooltip.hidden = false;
ally.element.focus(tooltip);
});
Такой подход делает подсказку доступной для клавиатуры и вспомогательных технологий.
Иногда тултип содержит интерактивные элементы — ссылки или кнопки. В этом случае необходимо предотвратить случайный переход фокуса за пределы контейнера.
Модуль ally.maintain.tabFocus позволяет ограничить перемещение фокуса.
const tabFocus = ally.maintain.tabFocus({
context: tooltip
});
После закрытия подсказки контроль фокуса должен быть отключён.
tabFocus.disengage();
После закрытия тултипа фокус должен возвращаться к исходному элементу. Это стандартная практика доступного интерфейса.
button.focus();
Полный пример:
button.addEventListener('click', () => {
tooltip.hidden = false;
ally.element.focus(tooltip);
});
function closeTooltip() {
tooltip.hidden = true;
button.focus();
}
Мобильные интерфейсы требуют явных способов закрытия подсказки. Возможные механизмы:
Пример обработки Escape:
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
tooltip.hidden = true;
button.focus();
}
});
Модуль ally.query.focusable помогает найти элементы внутри тултипа, способные получать фокус.
const focusable = ally.query.focusable({
context: tooltip
});
Это позволяет:
Пример:
const elements = ally.query.focusable({
context: tooltip
});
if (elements.length) {
ally.element.focus(elements[0]);
}
В мобильных системах (VoiceOver, TalkBack) подсказки должны корректно объявляться.
Основные рекомендации:
role="tooltip";aria-describedby;Дополнительный атрибут:
aria-live="polite"
Он сообщает экранному считывателю о появлении нового контента.
Если тултип скрыт, его элементы не должны получать фокус. Для этого используется модуль ally.element.disabled.
ally.element.disabled(tooltip);
После открытия подсказки доступность возвращается.
ally.element.disabled(tooltip, false);
Это предотвращает ситуацию, когда пользователь клавиатуры попадает в невидимый элемент.
Мобильные тултипы должны учитывать особенности сенсорных интерфейсов:
Размер области касания
Минимальная зона — около 44×44 px.
Избежание перекрытия контента
Подсказка не должна закрывать элемент управления.
Автоматическое позиционирование
Подсказка должна адаптироваться к положению на экране.
На мобильных устройствах экран меньше, поэтому подсказка может выходить за границы области просмотра.
Пример простого позиционирования:
const rect = button.getBoundingClientRect();
tooltip.style.top = rect.bottom + 'px';
tooltip.style.left = rect.left + 'px';
Более сложные системы используют:
Если тултип создаётся динамически, необходимо проверить его доступность.
if (!ally.is.focusable(tooltip)) {
tooltip.setAttribute('tabindex', '-1');
}
Это гарантирует возможность программной фокусировки.
Компонент обычно включает:
HTML
CSS
JavaScript
import ally from 'ally.js';
const button = document.getElementById('help-button');
const tooltip = document.getElementById('tooltip-help');
let focusTrap;
function openTooltip() {
tooltip.hidden = false;
focusTrap = ally.maintain.tabFocus({
context: tooltip
});
ally.element.focus(tooltip);
}
function closeTooltip() {
tooltip.hidden = true;
if (focusTrap) {
focusTrap.disengage();
}
button.focus();
}
button.addEventListener('click', () => {
if (tooltip.hidden) {
openTooltip();
} else {
closeTooltip();
}
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeTooltip();
}
});
Такой подход обеспечивает:
Использование hover-событий
На мобильных устройствах такие события не работают.
Автоматическое скрытие
Подсказка, исчезающая без действия пользователя, нарушает доступность.
Отсутствие связи через ARIA
Без aria-describedby экранный считыватель не сможет
связать подсказку с элементом.
Невидимые элементы в таб-порядке
Скрытые тултипы иногда остаются доступными для клавиатуры.
Современные интерфейсы всё чаще используют мобильные подсказки для:
Библиотека ally.js предоставляет низкоуровневые инструменты для управления фокусом и доступностью. Благодаря этому тултипы могут корректно работать в условиях сенсорного взаимодействия, поддерживать клавиатурную навигацию и обеспечивать полноценную интеграцию с вспомогательными технологиями.