CSS :user-invalid: ошибка после ввода
:user-invalid срабатывает, когда поле не прошло проверку после того, как пользователь с ним взаимодействовал. В отличие от :invalid, он не подсвечивает пустое обязательное поле сразу при загрузке страницы. Это уменьшает визуальный шум и не ругает пользователя до первой попытки ввода.
Подсветить ошибку и успех
input:user-invalid {
border-color: #b42318;
box-shadow: 0 0 0 3px #fecdca;
}
input:user-valid {
border-color: #067647;
}
input:user-invalid + .error {
display: block;
}
.error {
display: none;
color: #b42318;
}Псевдокласс работает с нативной валидацией: required, type="email", pattern, min, max, minlength. После ввода и потери фокуса браузер сам решает, когда показать состояние. Текст ошибки всё равно нужен рядом с полем: цвет и рамка не должны быть единственным сигналом.
Для стилизации родителя используйте :has(): .field:has(input:user-invalid) { ... }. Для доступности добавьте aria-invalid="true" и свяжите поле с текстом через aria-describedby. Нативная подсказка браузера может перекрывать ваш текст; при novalidate её нужно заменить собственной проверкой.
Поддержка есть в Chrome 119+, Firefox 88+ и Safari 16.5+. В старых браузерах правило игнорируется, поэтому базовые стили ошибки должны работать и без него. Не путайте :user-invalid с :invalid: второй применяется сразу и часто раздражает в пустых формах.
Серверная валидация обязательна независимо от CSS: клиентские проверки можно обойти. Не отключайте фокус и не скрывайте поле с ошибкой — пользователь должен понять, что исправить.
Документация: MDN :user-invalid, MDN :user-valid.