Меня зовут София. Я - CSS инженер. Это мой блог.

Если вам очень больно без стилей, вы можете их.

Нативная валидация ввода в CSS

Паттерны ввода

Обозначить паттерн

В случае, если поле имеет определенный формат (например email), можно использовать аттрибут pattern. Он принимает регулярное выражение, которому должно соответствовать введенное значение. При этом, если поле пустое, то проверки не производится, какая бы регулярка не была указана. Например, такой инпут принимает только заглавные английские буквы в любом количестве:

 <input pattern="[A-Z]+">

В случае, если пользователь ввел туда что-то кроме них, форма не будет отправлена (по button[type="submit"]), пока он не поменяет значение на правильное. Исключение - если у формы проставлен аттрибут novalidate.

Нативные паттерны

Некоторые типы инпутов добавляют свои паттерны ввода. Например, input[type="email"] требует ввести значение, содержащее символ @, а input[type="number"] принимает только числа.

Показать пользователю ошибку

Поможет псевдокласс :invalid. Он соответствует полям, значение которых не валидно, то есть не соответствует заданному паттерну (или это пустое обязательно поле, смотри дальше). Например, это правило подсветит красным такое поле:

:invalid {
  background-color: red;
}

Показать пользователю, что он правильно ввел

Поможет псевдокласс :valid. Он соответствует полям, значение которых валидно, то есть соответствует заданному паттерну. Например, это правило подсветит зеленым такое поле:

:valid {
  background-color: green;
}

По UX такой класс нужен довольно редко, но все же он есть.

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

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

Добавление к инпуту (не важно какого типа) атрибута required показывает системе, что это поле обязательно для ввода. То есть при отправке формы его значение должно быть не пустое.

<input required type="text">

Показать ошибку

Поможет псевдокласс :invalid. Как уже было сказано выше, он соответствует инпутам, значение которых невалидно. В данном случае не соответствует заданному паттерну "быть не пустым". Например, такое правило поможет подсветить красным поля, в которые пользователь ничего не ввел, но должен.

:invalid {
  background-color: red;
}

Не тыкать в пользователя ошибками, пока он ничего не сделал

В коде примера выше при первом заходе пользователя на страницу поле будет уже подсвечено красным цветом. А он даже не прочитал, что надо вводить и вообще что это за сайт. Неприятно. Решение: в новом черновике спецификации селекторов описан класс :user-invalid. Он соответствует тем полям, с которыми пользователь провзаимодействовал + срабатывает также после нажатия на button[type="submit"] или input[type="submit"]. В этом примере поле подсветится красным, только когда пользователь что-то в него введет, удалит и уберет фокус, или после нажатия на кнопку отправки формы:

<form action="">
  <label>
    Text
    <input required type="text">
  </label>
  <button type="submit">Submit</button>
</form>
<style>
input:user-invalid {
  background-color: red;
}
</style>

Прежде чем вы попытались опробовать этот пример в деле: сейчас это так НЕ работает. Поддержки селектора нет почти нигде. Только частично за префиксом в Firefox под другим именем. Подробнее на MDN про :-moz-ui-invalid. Альтернатива: js. По клику на кнопку отправки добавлять на форму класс, за этим классом и псевдоклассом :invalid прятать стили для невалидных полей. Полных полифиллов этого псевдокласса с поддержкой сложной механикой взаимодействия пользователя с полями на момент написания статьи еще не написано.

Специальные ограничения

maxLength & minLength

Аттрибуты maxLength и minLength позволяют ограничить длину ввода с двух сторон для текстовых полей. Это поле будет не валидным (:invalid), если в нем меньше 4 символов:

<input minLenght="4">

maxLenght работает по другому. В инпут с этим аттрибутом браузер не позволяет пользователю ввести больше указанного количества символов с клавиатуры. Тем не менее, при автозаполнении или с помощью JS туда можно ввести сколько угодно символом, но невалидным (:invalid), это значение не будет, более того, оно будет валидным (:valid).

max & min

Для некоторых не текстовых полей можно ограничить максимальное и минимальное значение с помощью аттрибутов max и min. Например:

<input type="number" min="1">
<input type="time" min="21:00" max="06:00" step="60">

Для контроля значения относительно заданных лимитов существуют псевдоклассы :in-range и :out-of-range. Эти псевдоклассы применяются только к элементам с заданным диапазоном ограничений. При отсутствии такого ограничения элемент не может быть ни "в зоне допустимых значений", ни "вне диапазона".

В этом примере инпут будет красным, если значение меньше 10 (включительно) или больше 20 (включительно), в остальных случаях (в том числе при пустом значении) он будет зеленым:

<input type="number" min="10" max="20">
<style>
:out-of-range {
  background-color: red;
}
:in-range {
  background-color: green;
}
</style>

Но! Чтобы не тыкать в пользователя сообщениями о правильности заполнения формы, пока он ничего не сделал, стили для :in-range почти никогда не пишут.

Источники

  1. Спецификация css-selectors-3

Post Scriptum

Вопросы и предложения пишите мне в телеграм @ariarzer :)

За помощь в написании и всём остальном спасибо @SelenIT2 и @dark_mefody ❤️