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

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

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

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

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

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

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

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

Исключение - если у формы проставлен атрибут novalidate.

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

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

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

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

:invalid {
  background-color: red;
}

Если вам нужно, чтобы селектор применился только к инпутам, обязательно пропишите нужный тег: input:invalid.

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

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

:valid {
  background-color: green;
}

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

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

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

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

<input required type="text">

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

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

:invalid {
  background-color: red;
}

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

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

input:user-invalid {
  background-color: red;
}

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

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

maxlength & minlength

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

<input minlength="4">

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

max & min

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

<input type="number" min="11">
<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 ❤️