Поддержка скринридеров

SVG-элементы по умолчанию не всегда корректно воспринимаются вспомогательными технологиями. Для обеспечения доступности необходимо использовать правильные атрибуты и структурирование элементов.

Атрибуты role и aria

Для обозначения функции SVG в контексте документа применяются атрибуты ARIA:

  • role="img" – сообщает скринридеру, что элемент является изображением.
  • aria-label="описание" – предоставляет краткое текстовое описание, которое будет озвучено.
  • aria-labelledby="id" – связывает SVG с элементом <title> внутри SVG, обеспечивая динамическое описание.
  • aria-hidden="true" – скрывает SVG от скринридеров, если элемент декоративный.

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

const draw = SVG().addTo('body').size(300, 200);
const rect = draw.rect(100, 100).fill('#3498db');
rect.attr({
  role: 'img',
  'aria-label': 'Синий квадрат размером 100 на 100 пикселей'
});

Элементы <title> и <desc>

  • <title> – краткий заголовок SVG. Обычно используется для идентификации объекта.
  • <desc> – более детальное описание. Поддерживается большинством современных скринридеров.

Пример:

const draw = SVG().addTo('body').size(300, 200);
const circle = draw.circle(80).fill('#e74c3c');

circle.node.innerHTML = `
  <title>Красный круг</title>
  <desc>Круг диаметром 80 пикселей, расположенный в центре области SVG</desc>
`;
circle.attr('role', 'img');

Использование <title> и <desc> повышает уровень доступности без изменения визуального отображения.

Декоративные элементы

Если SVG содержит декоративные элементы, которые не несут смысловой нагрузки, необходимо скрыть их от скринридеров:

const line = draw.line(0, 0, 300, 200).stroke({ width: 2, color: '#2ecc71' });
line.attr('aria-hidden', 'true');

Группировка и семантика

Группировка элементов через <g> позволяет логически структурировать содержимое. Для групп можно задавать ARIA-атрибуты, чтобы скринридер корректно озвучивал вложенные элементы:

const group = draw.group();
const rect1 = group.rect(50, 50).fill('#9b59b6');
const rect2 = group.rect(50, 50).move(60, 0).fill('#f1c40f');

group.attr({
  role: 'img',
  'aria-label': 'Два прямоугольника рядом, фиолетовый и желтый'
});

Интерактивные элементы

SVG.js позволяет создавать интерактивные элементы, такие как кнопки или области клика. Для доступности:

  • Использовать tabindex="0" для фокусируемых объектов.
  • Добавлять role="button" и соответствующие события клавиатуры (Enter, Space).
  • Использовать aria-pressed для переключателей.

Пример интерактивной кнопки:

const button = draw.rect(100, 40).fill('#1abc9c').radius(5);
button.attr({
  role: 'button',
  'aria-label': 'Кнопка отправки формы',
  tabindex: 0
});

button.on('keydown', (e) => {
  if (e.key === 'Enter' || e.key === ' ') {
    alert('Форма отправлена');
  }
});

Поддержка динамического контента

Для динамически обновляемых SVG необходимо обновлять ARIA-атрибуты и содержимое <title> или <desc>:

const rect = draw.rect(100, 100).fill('#e67e22');
const title = SVG().node('title').text('Начальный квадрат');
rect.add(title);

setTimeout(() => {
  rect.fill('#16a085');
  title.text('Квадрат изменил цвет на зеленый');
}, 2000);

Совместимость со скринридерами

  • VoiceOver (macOS, iOS) корректно озвучивает <title> и <desc>.
  • NVDA и JAWS (Windows) требуют наличия role="img" для SVG без прямой семантики.
  • Декоративные элементы без aria-hidden="true" могут быть лишними и нарушать восприятие.

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