Современные HTML-формы: доступность, валидация и UX
Форма — самая важная страница вашего сайта: без неё нет заявок. При этом формы — одно из самых «сломанных» мест в вебе: плейсхолдеры вместо лейблов, незаметные ошибки, недоступные select. В 2026 году у браузеров есть всё необходимое для отличных форм — без единой библиотеки. Разбираем современный подход.
Семантика: лейблы и поля
Первое правило: у каждого поля — видимый лейбл. Плейсхолдер не заменяет лейбл: он исчезает при вводе и непонятен скринридерам.
<label for="email">Email</label>
<input id="email" type="email" name="email"
autocomplete="email" required>
for+idсвязывают лейбл с полем — клик по лейблу фокусирует поле, скринридеры озвучивают название.autocomplete(email, name, tel, address…) — браузер подставляет данные автоматически, пользователи заполняют формы в разы быстрее.- Группируйте логически:
<fieldset>+<legend>для радио-групп и чекбоксов.
Типы полей: используйте нативные
Современные типы дают клавиатуру и валидацию бесплатно:
| Тип | Что даёт |
|---|---|
type="email" | Проверка формата, клавиатура с «@» на мобильных |
type="tel" | Телефонная клавиатура |
type="number" | Стрелки, валидация числа |
type="date" | Нативный календарь |
type="password" | Скрытие + генерация пароля в браузере |
type="search" | Кнопка очистки, поведение поиска |
Атрибуты: minlength/maxlength, min/max, pattern, inputmode (для цифровых клавиатур), enterkeyhint (подпись кнопки Enter).
Валидация: нативная + JS-усиление
Современный подход — validate on blur (проверка при уходе из поля), а не после отправки:
form.addEventListener('submit', (e) => {
if (!form.checkValidity()) {
e.preventDefault();
form.reportValidity(); // показывает нативные сообщения
}
});
// Усиление: своё сообщение вместо системного
input.addEventListener('invalid', () => {
input.setCustomValidity(input.validity.valueMissing
? 'Пожалуйста, заполните поле'
: input.validity.typeMismatch
? 'Похоже, это не email'
: '');
});
- Нативная валидация (атрибуты
required,type,pattern) работает без JS — это база. - Пользовательские сообщения — через
setCustomValidityи псевдокласс:user-invalid(стилизация ошибок только после ввода). - Серверная валидация обязательна всегда — клиентская не защита, а удобство.
Кастомизация select в 2026
Долгие годы <select> нельзя было стилизовать — теперь в HTML появились кастомизируемые select-элементы (Customizable Select), позволяющие полный контроль стилей при сохранении нативного поведения:
<select class="select">
<option>Обычный вариант</option>
<option>Ещё вариант</option>
</select>
/* CSS: стилизуем кнопку, стрелку, список и пункты */
.select::picker-icon { ... }
.select option:checked::before { content: "✓"; }
Это заменяет десятки JS-библиотек «кастомных селектов» с их багами доступности. Проверяйте поддержку (caniuse) и предусматривайте фолбэк на нативный select.
UX-детали, которые решают
- Ошибки рядом с полем, а не «сверху формы» — глаза пользователя уже у поля.
- Подсветка невалидного поля — цвет рамки + иконка + текст, а не только текст.
- Кнопка отправки с прогрессом: «Отправляем…» + блокировка двойного клика.
- Данные не теряются: перезагрузка/ошибка — восстанавливайте введённое (или это сделает autocomplete).
- Показывайте пароль (глазок) — снижает ошибки ввода.
- Focus-стили для клавиатуры — видимое кольцо фокуса на каждом элементе.
Безопасность при отправке
- Всегда серверная валидация и санитизация — клиент можно обойти.
- CSRF-токен для форм с изменением состояния.
- Капча (или honeypot-поле для лёгкой защиты) — спам в формах никуда не делся.
- Скорость: отправка через fetch с
FormDataбез перезагрузки страницы.
«Лучшая форма — та, что прощает ошибки и не задаёт вопросов. Современный HTML даёт 90% правильного UX из коробки — остаётся не сломать его библиотеками» — практика веб-разработки, 2026.
Пройдитесь по своим формам: лейблы вместо плейсхолдеров, autocomplete, нативная валидация с понятными сообщениями, focus-стили. Это час работы и заметный рост конверсии.