HTML5 формы и валидация: практическое руководство с примерами

Запрос, под который оптимизирована статья: HTML5 валидация форм. Ниже — компактное и практичное руководство, которое поможет собрать удобную и доступную форму с нативной валидацией без лишнего JavaScript, а при необходимости — расширить её Constraint Validation API.
Почему стоит использовать нативную валидацию HTML5
- Меньше кода: браузер уже умеет проверять required, type, min/max, pattern и т. д.
- Лучшая мобильная клавиатура: правильный type включает нужную раскладку (почта, цифры, телефон).
- Доступность из коробки: связка label + input и валидаторы озвучиваются скринридерами.
- SEO косвенно выигрывает: корректные формы улучшают UX и поведенческие метрики.
Базовая разметка формы (доступная и гибкая)
<form id='signup' action='/signup' method='post' novalidate>
<fieldset>
<legend>Регистрация</legend>
<div class='field'>
<label for='email'>Email</label>
<input id='email' name='email' type='email' required autocomplete='email' placeholder='you@example.com'>
<small id='email-hint' class='hint'>Мы отправим письмо для подтверждения.</small>
</div>
<div class='field'>
<label for='password'>Пароль</label>
<input id='password' name='password' type='password' required minlength='8' autocomplete='new-password'>
<small class='hint'>Минимум 8 символов</small>
</div>
<div class='field'>
<label for='tel'>Телефон</label>
<input id='tel' name='tel' type='tel' inputmode='tel' autocomplete='tel' placeholder='+7 900 000-00-00' pattern='^[+0-9\s()-]{10,}$'>
<small class='hint'>Только цифры, пробелы, +, скобки и дефисы</small>
</div>
<button type='submit'>Создать аккаунт</button>
</fieldset>
<div class='form-status' aria-live='polite'></div>
</form>
<style>
.field { margin-bottom: 12px; }
input:required:invalid { border-color: #e74c3c; }
input:valid { border-color: #2ecc71; }
.hint { color: #666; font-size: 12px; }
</style>
Ключевые моменты: используйте label с атрибутом for, включайте autocomplete, при необходимости добавляйте inputmode и pattern. Атрибут novalidate на форме позволяет контролировать показ ошибок вручную через JS, но вы можете его убрать, если хотите полностью полагаться на встроенные подсказки браузера.
Типы полей HTML5, которые упрощают жизнь
<input type='email' autocomplete='email'> <!-- проверка email и клавиатура с @ -->
<input type='url' autocomplete='url'> <!-- проверка URL -->
<input type='tel' inputmode='tel'> <!-- цифровая клавиатура на мобильных -->
<input type='number' min='0' max='10' step='1'>
<input type='date'> <input type='time'> <input type='datetime-local'>
<input type='range' min='0' max='100' value='50'>
<input type='color'>
Советы:
- email и url: не пытайтесь переписать их проверку через сложные regexp — доверьтесь браузеру, при необходимости уточняйте pattern.
- tel: валидировать международные форматы лучше на сервере; в HTML ограничьте допустимые символы через pattern.
- number: помните про локали — лучше отправлять значения как строки и валидировать на сервере, если требуется точность с десятичными разделителями.
Нативная валидация: required, minlength, pattern и друзья
<input type='password' required minlength='8'>
<input type='text' pattern='^[A-Za-z\s-]{2,}$' title='Только латинские буквы, пробел и дефис'>
<input type='number' min='18' max='99' required>
Атрибут title показывает подсказку при ошибке pattern. Если хотите единый стиль сообщений, используйте Constraint Validation API и собственные подсказки (см. ниже).
Стили состояний: :valid и :invalid без JS
<style>
input:focus { outline: 2px solid #2684ff33; }
input:required:invalid:not(:placeholder-shown) { border-color: #e74c3c; }
input:required:valid { border-color: #2ecc71; }
.error { color: #e74c3c; font-size: 12px; }
</style>
Хитрость с :placeholder-shown помогает не красить пустое поле красным до первого ввода пользователя.
Constraint Validation API: свои сообщения и контроль отправки
<script>
const form = document.getElementById('signup');
const status = form.querySelector('.form-status');
function showFieldError(input, message) {
input.setCustomValidity(message || '');
input.reportValidity();
}
form.addEventListener('input', (e) => {
const el = e.target;
if (el instanceof HTMLInputElement) {
// Сбрасываем кастомную ошибку при вводе
el.setCustomValidity('');
}
});
form.addEventListener('submit', (e) => {
// Кастомные правила поверх нативных
const email = form.email;
const pass = form.password;
if (email && email.validity.typeMismatch) {
showFieldError(email, 'Введите корректный email');
e.preventDefault();
return;
}
if (pass && pass.value && !/[0-9]/.test(pass.value)) {
showFieldError(pass, 'Пароль должен содержать хотя бы одну цифру');
e.preventDefault();
return;
}
if (!form.checkValidity()) {
// Попросим браузер показать стандартные подсказки
form.reportValidity();
e.preventDefault();
return;
}
status.textContent = 'Отправляем...';
});
</script>
Методы, которые нужно знать:
- checkValidity() — возвращает true, если форма валидна.
- reportValidity() — показывает встроенные подсказки браузера.
- setCustomValidity(msg) — устанавливает ваше сообщение об ошибке для конкретного поля.
Доступность: label, подсказки и aria-live
- Каждое поле связывайте с label по for. Не заменяйте label плейсхолдером — плейсхолдер исчезает при вводе.
- Для текстовых подсказок используйте aria-describedby или визуально связанный <small> рядом с инпутом.
- Для общих статусов формы применяйте контейнер с aria-live='polite' — скринридеры озвучат изменения.
- Не отключайте outline: он нужен для клавиатурной навигации.
Безопасность: помните про серверную валидацию
HTML5 проверка — это удобный первый барьер. Но бизнес-правила, ограничения и безопасность всегда дублируются на сервере. Клиентскую валидацию можно обойти, поэтому сервер должен заново проверять все поля и возвращать понятные ошибки пользователю.
Продвинутые приёмы для форм
<!-- Автозаполнение: подсказываем браузеру структуру данных -->
<input name='given-name' autocomplete='given-name'>
<input name='family-name' autocomplete='family-name'>
<input name='address-line1' autocomplete='address-line1'>
<input name='postal-code' autocomplete='postal-code' inputmode='numeric'>
<!-- Загрузка файлов -->
<input type='file' name='avatar' accept='image/*' capture='environment'>
<!-- Группировка полей и доступность -->
<fieldset>
<legend>Способ доставки</legend>
<label><input type='radio' name='delivery' value='courier' required> Курьер</label>
<label><input type='radio' name='delivery' value='pickup'> Самовывоз</label>
</fieldset>
Чек-лист HTML5 валидации перед релизом
- Выбраны корректные type для всех полей (email, tel, url, number, date...).
- Настроены autocomplete и, при необходимости, inputmode.
- Добавлены required, min/max, minlength/maxlength, pattern и понятные title.
- Стили для :invalid и :valid не мешают доступности (outline сохранён).
- Серверная валидация дублирует критичные правила и возвращает ошибки в удобном формате.
- Тест на мобильных: клавиатура, автозаполнение, зумабельность, фокусные кольца.
Где прокачать вёрстку форм на практике
Если хотите системно подтянуть навыки HTML и CSS, собрать реальные макеты и отточить работу с формами, посмотрите курс: Вёрстка сайта с нуля 2.0 — пошаговый практикум по современной вёрстке. Хорошо подходит новичкам и тем, кто закрепляет базу перед первым проектом или стажировкой.
Итоги
HTML5 формы покрывают 80% сценариев без сторонних библиотек: правильные типы полей, нативная валидация и немного CSS. Когда нужно больше контроля — подключайте Constraint Validation API и аккуратно расширяйте правила. Так вы получите быстрые, доступные и надёжные формы, которые приятно заполнять пользователям.
-
-
Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.