Валидация форм на 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:
- Сообщим пользователю о требуемом формате, когда фокус находится в поле ввода
- Напомним ему, если введенные данные не будут валидными
Но еще… не показывайте никаких подсказок, если поле пустое. И не считайте его неверно заполненным. Это может создать ощущение назойливости и будет только раздражать. Для того, чтобы соблюсти эту рекомендацию, мы должны будем узнать, пустое поле или нет.
Проверяем заполнено поле или нет
Мы хотим провернуть фокус с :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 может работать не очень хорошо. Это просто пример! Не стесняйтесь брать по частям или менять под свои нужды.
See the Pen
Form with a bunch of HTML5 Validation and CSS3 Help by Chris Coyier (@chriscoyier)
on CodePen.