Доступность тултипов

Тултип (tooltip) — это всплывающий элемент, который предоставляет дополнительную информацию о компоненте интерфейса при наведении или фокусе. В контексте доступности важно, чтобы тултип был видимым и воспринимаемым всеми пользователями, включая тех, кто использует экранные читалки или клавиатурную навигацию.

React Aria предоставляет набор хуков и утилит для реализации доступных тултипов, соответствующих спецификациям ARIA. Ключевым элементом является useTooltip, который управляет состоянием тултипа, его привязкой к элементу и взаимодействием с пользователем.


useTooltipTrigger и useTooltip

Для корректной работы тултипа требуется два основных хука:

  1. useTooltipTrigger — управляет триггером, то есть элементом, при наведении или фокусе на котором будет отображаться тултип.
  2. useTooltip — управляет самим тултипом, его атрибутами и поведением с точки зрения доступности.

Пример использования:

import { useTooltip, useTooltipTrigger } from '@react-aria/tooltip';
import { useTooltipTriggerState } from '@react-stately/tooltip';
import { useRef } from 'react';

function TooltipExample() {
  const state = useTooltipTriggerState({});
  const triggerRef = useRef();
  const tooltipRef = useRef();

  const { triggerProps, tooltipProps } = useTooltipTrigger(
    { type: 'hover', delay: 500 },
    state,
    triggerRef
  );

  const { tooltipProps: ariaTooltipProps } = useTooltip(tooltipProps, tooltipRef);

  return (
    <>
      <button {...triggerProps} ref={triggerRef}>
        Наведи на меня
      </button>
      {state.isOpen && (
        <div {...ariaTooltipProps} ref={tooltipRef}>
          Это тултип с описанием
        </div>
      )}
    </>
  );
}

В этом примере:

  • useTooltipTriggerState управляет состоянием видимости тултипа (isOpen).
  • triggerProps содержат атрибуты ARIA (aria-describedby), связывающие триггер и тултип.
  • tooltipProps и ariaTooltipProps обеспечивают правильную семантику и поведение.

Атрибуты ARIA для тултипов

Правильное использование атрибутов ARIA критично для доступности:

  • aria-describedby — указывает на идентификатор элемента тултипа, связывая его с триггером.
  • role="tooltip" — сообщает вспомогательным технологиям, что элемент является подсказкой.
  • aria-hidden — используется для скрытия тултипа от экранных читалок, когда он не видим.

React Aria автоматически добавляет эти атрибуты через хуки, обеспечивая соответствие спецификациям WAI-ARIA.


Управление состоянием видимости

Тултип должен появляться при наведении мыши или фокусе на клавиатуре и скрываться при уходе курсора или потере фокуса. React Aria использует useTooltipTriggerState для централизованного управления состоянием:

  • isOpen — отображается ли тултип.
  • open() / close() — методы для программного управления.
  • toggle() — переключение состояния.

Параметр delay позволяет задать задержку перед отображением, что улучшает UX и предотвращает мерцание тултипа при быстрых движениях курсора.


Поддержка клавиатурной навигации

Доступные тултипы должны быть видимы при фокусе с клавиатуры. React Aria учитывает это, автоматически добавляя обработчики событий для:

  • onFocus — открытие тултипа при фокусе.
  • onBlur — закрытие при потере фокуса.
  • onMouseEnter / onMouseLeave — открытие и закрытие при наведении мыши.

Такой подход гарантирует корректное взаимодействие как для мыши, так и для клавиатуры.


Позиционирование тултипов

React Aria интегрируется с библиотекой React Spectrum или утилитами вроде @react-aria/overlays для управления позиционированием. Тултип можно привязать к триггеру с учетом:

  • Направления (top, bottom, left, right)
  • Смещения (offset)
  • Автоматического подбора позиции при нехватке места

Пример использования с useOverlayPosition:

import { useOverlayPosition } from '@react-aria/overlays';

const { overlayProps, placement } = useOverlayPosition({
  targetRef: triggerRef,
  overlayRef: tooltipRef,
  placement: 'top',
  offset: 8
});

Это обеспечивает адаптивное отображение тултипа и предотвращает его обрезание за пределами экрана.


Важные рекомендации

  • Использовать семантические элементы и роли (role="tooltip").
  • Обеспечивать фокусируемость триггера, чтобы пользователи клавиатуры могли увидеть тултип.
  • Поддерживать короткие и информативные тексты, избегая перегруженности контента.
  • Настраивать задержку отображения, чтобы избежать резких всплытий при случайном наведении.
  • Проверять доступность с экранными читалками и клавиатурой, чтобы гарантировать соответствие стандартам WCAG.

Примеры сложных сценариев

  1. Тултип внутри модального окна — следует использовать Portal, чтобы тултип не оказался за пределами модального контейнера.
  2. Многострочные тултипы — React Aria автоматически управляет фокусом и aria-describedby, но текст должен оставаться кратким и структурированным.
  3. Динамически изменяющийся контент — важно вызывать обновление состояния тултипа через state.open() при изменении текста или условий отображения.

Итоговые ключевые моменты

  • React Aria обеспечивает корректное управление ARIA-атрибутами, фокусом и событиями.
  • Использование useTooltipTrigger, useTooltip и useTooltipTriggerState позволяет создавать доступные тултипы для любых компонентов.
  • Позиционирование через useOverlayPosition делает тултипы адаптивными и предотвращает перекрытия интерфейса.
  • Соблюдение семантики и UX рекомендаций гарантирует соответствие стандартам доступности и удобство для всех пользователей.

Тщательная интеграция этих подходов обеспечивает создание тултипов, которые будут корректно работать для пользователей с разными способами взаимодействия с интерфейсом.