Перейти к основному содержимому
    Назад к блогу
    РазработкаОпубликовано 12 октября 2026 г.

    Доступные формы: подписи, подсказки, ошибки и автозаполнение

    Как сделать форму, которую можно заполнить со скринридером, с клавиатуры и без лишних усилий: label, autocomplete, fieldset, сообщения об ошибках

    Доступные формы: подписи, подсказки, ошибки и автозаполнение

    Часть 3 из 8 серии «Доступный веб на практике». Предыдущая часть: Семантический HTML и альтернативный текст: фундамент доступного сайта.

    Форма — место, где пользователь ближе всего к цели, и место, где он чаще всего застревает: у половины популярных сайтов есть поля без подписей. Разбираем, как сделать формы, которые заполняются легко — со скринридером, с клавиатуры и с менеджером паролей.

    Формы

    У каждого поля — видимая подпись

    <!-- ❌ Placeholder вместо подписи -->
    <input type="email" placeholder="Email">
    
    <!-- ✅ -->
    <label for="email">Электронная почта</label>
    <input type="email" id="email" name="email" autocomplete="email">
    

    Почему placeholder не заменяет подпись:

    • исчезает при вводе — человек забывает, что вводит, особенно при проблемах с памятью и вниманием;
    • обычно слишком бледный и не проходит по контрасту;
    • поддержка его как доступного имени неоднородна.

    Связь for + id даёт сразу три вещи: скринридер читает подпись при фокусе на поле, голосовое управление находит поле по подписи, а клик по подписи ставит фокус в поле — это увеличивает зону нажатия, особенно для флажков.

    Подсказки и формат

    <label for="phone">Телефон</label>
    <p id="phone-hint" class="hint">Например, +1 503 555 0100</p>
    <input type="tel" id="phone" name="phone"
           autocomplete="tel"
           aria-describedby="phone-hint">
    

    aria-describedby прочитает подсказку после имени поля. Подсказка видима всем, а не спрятана в тултипе.

    Атрибут autocomplete

    Атрибут autocomplete с правильными токенами (name, email, tel, street-address, postal-code, cc-number, one-time-code и др.) позволяет браузеру заполнить форму за человека. Для людей с моторными и когнитивными нарушениями это огромная разница, а WCAG выделяет это в отдельный критерий 1.3.5 Identify Input Purpose. Полный список токенов — в спецификации HTML и на MDN.

    Группы полей

    Радиокнопки и флажки, объединённые общим вопросом, группируются через <fieldset> и <legend>:

    <fieldset>
      <legend>Удобный способ связи</legend>
    
      <input type="radio" id="contact-phone" name="contact" value="phone">
      <label for="contact-phone">Телефон</label>
    
      <input type="radio" id="contact-email" name="contact" value="email">
      <label for="contact-email">Электронная почта</label>
    </fieldset>
    

    Без legend пользователь скринридера услышит «Телефон, переключатель» и не поймёт, о чём вопрос.

    Обязательные поля

    <label for="name">Имя <span aria-hidden="true">*</span></label>
    <input type="text" id="name" name="name" required autocomplete="name">
    

    Атрибут required сообщает скринридеру «обязательное». Звёздочка — визуальная подсказка, скрытая от скринридера, чтобы он не читал «звёздочка». В начале формы поясните: «Поля со звёздочкой обязательны».

    Ошибки

    Хорошее сообщение об ошибке:

    1. видно — рядом с полем, не только красной рамкой;
    2. связано с полем программно;
    3. объясняет, как исправить, а не просто «Неверный формат»;
    4. объявляется при отправке, а фокус переходит к первой ошибке.
    <label for="email">Электронная почта</label>
    <input type="email" id="email" name="email"
           autocomplete="email"
           aria-invalid="true"
           aria-describedby="email-error">
    <p id="email-error" class="error">
      <svg aria-hidden="true" focusable="false">...</svg>
      Адрес должен содержать символ @, например name@example.com
    </p>
    
    // При отправке: проверяем, показываем ошибки и переводим фокус к первой
    form.addEventListener('submit', (event) => {
      const invalid = [...form.elements].filter((el) => el.willValidate && !el.checkValidity());
      if (invalid.length === 0) return;
    
      event.preventDefault();
      invalid.forEach((field) => showError(field)); // ставит aria-invalid и текст ошибки
      invalid[0].focus();
    });
    

    При длинной форме полезна сводка ошибок в начале со ссылками на поля — такой подход используют, например, в дизайн-системе GOV.UK (GOV.UK Error summary).

    Обратите внимание на иконку: ошибка не должна передаваться только цветом (подробнее в Контраст, анимация и размер кнопок: визуальная доступность сайта).

    Не ломайте вставку и менеджеры паролей

    Критерий 3.3.8 из WCAG 2.2 прямо говорит: вход не должен требовать запоминания или перепечатывания. На практике:

    <!-- ✅ Даём менеджеру паролей сделать свою работу -->
    <input type="email" id="login" autocomplete="username">
    <input type="password" id="password" autocomplete="current-password">
    
    <!-- Для кода из SMS -->
    <input type="text" inputmode="numeric" autocomplete="one-time-code">
    

    И не запрещайте вставку (onpaste="return false") в поле пароля или кода — это ничего не защищает, но мешает всем.

    Серия «Доступный веб на практике»

    1. Доступность сайта: для кого она на самом деле и с чего начать
    2. Семантический HTML и альтернативный текст: фундамент доступного сайта
    3. Доступные формы: подписи, подсказки, ошибки и автозаполнение — вы здесь
    4. Клавиатура и фокус: как сделать сайт, которым можно пользоваться без мыши
    5. Контраст, анимация и размер кнопок: визуальная доступность сайта
    6. ARIA и динамический контент: когда атрибуты помогают, а когда вредят
    7. Доступность в React: id, фокус при смене маршрута и объявления
    8. Как тестировать доступность: автоматика, ручная проверка и чеклист

    Следующая часть: Клавиатура и фокус: как сделать сайт, которым можно пользоваться без мыши

    Agama Labs — разработка сайтов и веб-приложений. Если хотите проверить доступность своего сайта, напишите нам: hello@agamalabs.com

    Контакты

    Давайте обсудим ваш проект

    Оставьте заявку, и мы свяжемся с вами в течение 2 часов для бесплатной консультации. Расскажите о вашей идее — поможем найти оптимальное решение.

    Время работы

    Пн–Пт: 08:00 – 17:00 (PST)
    Сб–Вс: Выходной

    Оставить заявку

    Заполните форму, и мы перезвоним вам

    Нажимая кнопку, вы соглашаетесь с политикой конфиденциальности

    Мы ценим вашу конфиденциальность

    Мы используем аналитические cookies, в том числе сторонних сервисов, чтобы понимать, как используется сайт, и улучшать его