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

Общие принципы доступности числовых полей

Работа с числовыми форматированными полями в веб-приложениях требует строгого соблюдения принципов доступности, поскольку любое вмешательство в отображение значения может повлиять на интерпретацию данных вспомогательными технологиями. Библиотека AutoNumeric, выполняющая автоматическое форматирование чисел (разделители тысяч, валютные символы, фиксированные десятичные знаки), должна интегрироваться таким образом, чтобы не нарушать требования WCAG 2.1/2.2.

Ключевая проблема заключается в различии между визуальным представлением значения и его семантическим содержимым, которое воспринимается скринридерами. Любое изменение DOM-значения input может приводить к рассинхронизации между тем, что видит пользователь, и тем, что озвучивает вспомогательная технология.


Семантика input-элементов и роль AutoNumeric

HTML-элемент <input> с типом text или tel часто используется для числовых значений при применении AutoNumeric, поскольку стандартный type="number" конфликтует с форматированием (например, не допускает пробелы или валютные символы).

Для обеспечения доступности необходимо сохранять корректную семантику:

  • role="textbox" (явно или по умолчанию)
  • aria-live не должен применяться к полю ввода напрямую
  • значение value должно оставаться валидным числом без визуальных разделителей в доступной модели данных

AutoNumeric при этом изменяет отображаемое значение, но не должен ломать логическую структуру поля.

Пример инициализации:

new AutoNumeric('#amount', {
  digitGroupSeparator: ' ',
  decimalCharacter: ',',
  currencySymbol: '₸ ',
  unformatOnSubmit: true
});

Проблема двойного представления значения

В контексте WCAG критично разделение:

  • ARIA/DOM value — чистое числовое значение
  • визуальное значение — форматированное представление

Нарушение возникает, когда AutoNumeric записывает форматированное значение в value, например:

1 234 567,89

Вспомогательные технологии могут интерпретировать это как текстовую строку, а не число.

Решение заключается в использовании механизма хранения «сырых» данных:

  • getNumericString()
  • getNumber()
  • unformat()

и обязательной синхронизации перед отправкой формы.


ARIA-атрибуты и корректная идентификация поля

Для обеспечения соответствия WCAG 1.3.1 (информация и отношения) и 4.1.2 (имя, роль, значение), поле должно быть явно описано:

<label for="amount">Сумма</label>
<input id="amount" type="text" aria-describedby="amount-hint amount-error">
<div id="amount-hint">Введите сумму в тенге</div>
<div id="amount-error" aria-live="polite"></div>

AutoNumeric не должен удалять или перезаписывать aria-* атрибуты при форматировании.

Особое внимание:

  • aria-describedby должен сохраняться неизменным
  • aria-invalid должен устанавливаться при ошибках валидации
  • aria-live используется только для внешних сообщений, не для input

Управление ошибками и aria-invalid

При интеграции с валидацией необходимо синхронизировать состояние поля:

function validateAmount(anElement) {
  const value = anElement.getNumber();

  const isValid = value >= 0 && value <= 1000000;

  const input = document.querySelector('#amount');

  if (!isValid) {
    input.setAttribute('aria-invalid', 'true');
  } else {
    input.removeAttribute('aria-invalid');
  }
}

WCAG требует, чтобы ошибка:

  • была программно определяемой
  • была связана с полем через aria-describedby
  • не полагалась только на цвет или визуальный стиль

Клавиатурная доступность и поведение курсора

Одним из критических аспектов является взаимодействие AutoNumeric с кареткой ввода.

WCAG 2.1.1 (Keyboard) требует, чтобы все функции были доступны с клавиатуры. AutoNumeric может нарушать UX при:

  • пересчёте позиции курсора после форматирования
  • вставке разделителей тысяч во время набора
  • перезаписи строки при каждом input событии

Правильное поведение включает:

  • сохранение позиции каретки до форматирования
  • восстановление позиции после изменения value
  • отсутствие блокировки стандартных клавиш (ArrowLeft, ArrowRight, Backspace)

Скринридеры и проблема «шумного ввода»

При каждом вводе символа AutoNumeric может триггерить обновление значения, что приводит к повторным озвучиваниям скринридером.

Это нарушает WCAG 1.3.2 (Meaningful Sequence) и 4.1.3 (Status Messages), если обновления слишком частые.

Рекомендуемые подходы:

  • минимизация DOM-обновлений (debounce форматирования)
  • отключение агрессивного live-обновления
  • использование aria-live="polite" только для итоговых сообщений

Inputmode и мобильные устройства

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

<input id="amount" type="text" inputmode="decimal">

или:

inputmode="numeric"

Это обеспечивает корректную клавиатуру без потери поддержки форматирования AutoNumeric.

Важно, что type="number" не используется, поскольку:

  • запрещает пробелы и валютные символы
  • конфликтует с локализацией
  • ломает кастомное форматирование

Обработка paste-событий и доступность

Вставка текста является важным сценарием WCAG, так как альтернативные устройства ввода часто используют буфер обмена.

AutoNumeric должен:

  • корректно очищать вставляемое значение
  • не блокировать paste без уведомления
  • сохранять доступность при массовой вставке чисел

Пример обработки:

element.addEventListener('paste', (e) => {
  setTimeout(() => {
    element.setAttribute('aria-invalid', String(!element.checkValidity?.()));
  }, 0);
});

Контраст и визуальное форматирование чисел

Хотя AutoNumeric не управляет стилями напрямую, форматирование может усиливать проблемы восприятия:

  • разделители тысяч должны иметь достаточный контраст
  • валютные символы не должны сливаться с числом
  • отрицательные значения должны быть различимы не только цветом

WCAG 1.4.3 (Contrast Minimum) и 1.4.1 (Use of Color) требуют:

  • дополнительного текстового обозначения минуса при необходимости
  • избегания передачи информации только через цвет

Синхронизация состояния формы

При использовании AutoNumeric внутри форм критично разделение:

  • UI-значение (formatted)
  • submit-значение (unformatted)

Типичная схема:

const an = new AutoNumeric('#amount', { unformatOnSubmit: true });

form.addEventListener('submit', () => {
  const numeric = an.getNumber();
  hiddenInput.value = numeric;
});

Это предотвращает отправку локализованных строк, которые могут быть неправильно интерпретированы сервером или вспомогательными системами.


Динамическое обновление значений и live regions

При изменении значения извне (например, пересчёт суммы):

  • обновление не должно происходить через innerText
  • сообщения должны быть отделены от input
  • aria-live применяется только к статусным блокам
<div aria-live="polite" id="status"></div>

AutoNumeric не должен напрямую взаимодействовать с live regions, чтобы избежать дублирования озвучивания.


Поведение при ошибках форматирования

Некорректные вводы (например, несколько десятичных разделителей) должны:

  • блокироваться без «тихого» удаления символов
  • сопровождаться доступным объяснением
  • не приводить к потере фокуса

WCAG 3.3.1 (Error Identification) требует явной идентификации ошибки, а не скрытой коррекции.


Совместимость с вспомогательными технологиями

Основные риски при интеграции AutoNumeric:

  • рассинхронизация value и визуального текста
  • частые DOM-обновления, вызывающие шум скринридеров
  • потеря позиции курсора
  • отсутствие явной семантики ошибки

Корректная интеграция строится вокруг принципа:

  • форматирование только отображения
  • данные всегда остаются чистыми
  • доступность обеспечивается через ARIA и стабильную структуру DOM