Button with success/error states

Валидация форм на HTML и CSS

Вы можете добиться внушительных результатов в вопросе проверки форм исключительно при помощи HTML-атрибутов. Вы можете сделать пользовательский опыт простым и понятным при помощи CSS-селекторов. Но вам потребуется несколько трюков, чтобы все получилось правильно!

(Вы можете) сделать label похожим на placeholder

Во-первых: всегда используйте настоящий элемент <label for=”correct_input”>. Игнорирование одного этого правила из соображений UX портит очень много форм. Плейсхолдер — всего лишь подсказка того, как должна выглядеть валидная информация в поле ввода, типа “введи Москва в поле под названием Город”.

Я бы сказал, что если форма короткая и с понятным паттерном поведения (вход или регистрация), то вы можете сделать названия полей в виде плейсхолдеров, но используйте для этого реальные элементы label.

Создадим форму

<form action=”#0" method=”post”> 
<div>
<input type=”text” id=”first_name” name=”first_name”>
<label for=”first_name”>First Name</label>
</div> <! — … — ->
</form>

Используем <div> для позиционирования и размещения названия поля непосредственно поверх самого поля.

SCSS
form {
max-width: 450px;

// позиционируем
> div {
position: relative;
   // Похоже на плейсхолдер
> label {
opacity: 0.3;
position: absolute;
top: 0;
left: 10px;
}
}
}

Вам не нужно хитро изворачиваться и беспокоиться об установке курсора в поле ввода, все уже сделано семантикой. Если пользователь нажимает на название поля — активируется поле ввода. Если нажимает на само поле — курсор устанавливается в поле ввода. Оба варианта верны.

Фишка в том, чтобы поставить поле ввода первым (семантически допустимо). Таким образом вы сможете скрывать label при фокусе:

SCSS
form {

/* … */
  > div {
> input[type=”text”],
> input[type=”email”],
> input[type=”password”] {
      &:focus {
& + label {
opacity: 0;
}
}
}
}
}

Сделайте определенные поля обязательными

Пожалуй, самым простым способом проверки формы является использование атрибута required. Нет более быстрого пути отлова ошибок, кроме как позволить браузеру сделать это самому!

<input required type=”text” id=”first_name” name=”first_name”>

Подсвечивайте верно заполненные поля

Дайте пользователю знать, что поле было заполнено верно. Браузер может предоставить нам эту информацию по CSS-псевдоклассу :valid.

SCSS
form {
> input[type=”text”],
> input[type=”email”],
> input[type=”password”] {

// покажите успех!
&:valid {
background: url(images/check.svg);
background-size: 20px;
background-repeat: no-repeat;
background-position: 20px 20px;
      // продолжаем прятать label
& + label {
opacity: 0;
}
}
}
}
}

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


Покажите напоминание о виде вводимых данных

Вы также можете установить определенное требуемое значение. Вроде email или number. Здесь перечислены все возможные варианты.

<input type=”email” id=”email” name=”email” required>

Это поле является обязательным для заполнения и вводимая информация будет проверяться на соответствие адресу электронной почты. Давайте улучшим UX:

  1. Сообщим пользователю о требуемом формате, когда фокус находится в поле ввода
  2. Напомним ему, если введенные данные не будут валидными

Но еще… не показывайте никаких подсказок, если поле пустое. И не считайте его неверно заполненным. Это может создать ощущение назойливости и будет только раздражать. Для того, чтобы соблюсти эту рекомендацию, мы должны будем узнать, пустое поле или нет.

Проверяем заполнено поле или нет

Мы хотим провернуть фокус с :valid и :invalid, но мы не хотим опережать события и считать поле невалидным до того, как оно было заполнено.

Есть ли CSS-селектор для проверки пустоты поля? Вообще-то нет! Вы можете подумать на :empty, но ошибетесь. Этот псевдокласс предназначен для проверки ситуаций когда элемент <p></p> не содержит в себе ничего. Поля ввода и так пусты по умолчанию.

Трюк в том, чтобы проверить поле на видимость атрибута placeholder:

CSS
input:not(:placeholder-shown) { }

Мы не использовали плейсхолдер в нашем примере, но это правило сработает, если мы зададим значение из одного пробела:

<input placeholder=” “>

:placeholder-shown супер полезен для нас! Это в целом секретный селектор, позволяющий проверить, есть ли в поле значение или нет.

IE и Firefox пока не поддерживают его, что немного осложняет задачу. Обычно спасителем является новая функция @supports, но…

CSS
/* Это не сработает */
@supports (input:placeholder-shown) {
input:not(:placeholder-shown) {
}
}

Вы не можете использовать @supports для селекторов, только для свойства/значения (например @supports (display: flex)).

Проверить плейсхолдер при помощи JavaScript довольно легко:

JavaScript
var i = document.createElement(‘input’);
if (‘placeholder’ in i) { }

Но это не кажется самым простым способом имитации :placeholder-shown. Поэтому…возможно, просто стоит подождать поддержки всеми браузерами.

Представим, что поддержка уже повсеместная и посмотрим, как это будет выглядеть…

SCSS
form {
  > div {

> input[type=”text”],
> input[type=”email”],
> input[type=”password”] {

// Когда поле ввода…
// 1. НЕ пустое
// 2. НЕ в фокусе
// 3. НЕ валидно
      &:invalid:not(:focus):not(:placeholder-shown) {
// Покажем напоминание
        background: pink;
& + label {
opacity: 0;
}
}

// Когда в невалидное поле устанавливается фокус (и оно по прежнему не пустое)
    &:invalid:focus:not(:placeholder-shown) {
// Покажем более настойчивое напоминание
& ~ .requirements {
max-height: 200px;
padding: 0 30px 20px 50px;
}
}
}

// <input> ~
// <label> ~
// <div class=”requirements”>
.requirements {
padding: 0 30px 0 50px;
color: #999;
max-height: 0;
transition: 0.28s;
overflow: hidden;
color: red;
font-style: italic;
}
}
}

Вы можете создать более сильную проверку

Это уже не просто required или type=”email” (и подобные). Вы можете проверить на клиентской стороне такие вещи, как длину (например минимальную длину пароля или максимальное количество символов в <textarea>) и даже использовать полноценное регулярное выражение.

Вот статья об этом. Скажем, вы хотите проверку пароля по параметрам:

  • Состоит из 6 символов
  • Содержит хотя бы одну прописную букву
  • Содержит хотя бы одну строчную букву
  • Содержит хотя бы одну цифру

Вы можете это сделать следующим образом:

<input pattern=”(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}” type=”password” id=”password” name=”password” required placeholder=” “>

Демо

Я оставил в этом примере :placeholder-shown, так что в Firefox и IE может работать не очень хорошо. Это просто пример! Не стесняйтесь брать по частям или менять под свои нужды.


P.S. Если вам понравилась эта статья — нажмите зеленое сердечко. Это много значит для меня. Спасибо!

Нашли ошибку? Воспользуйтесь функцией Private notes: выделяете текст с ошибкой, нажимаете на символ замка в появившемся дудле и оставляете свой комментарий. Спасибо!

Перевод статьи Form Validation UX in HTML and CSS Криса Койера.