Создание более дружественных, понятных веб-форм
Russian (Pусский) translation by Alex Grigorovich (you can also view the original English article)
Веб-формы всегда оставалась горячей темой, когда дело касалось веб-дизайна и взаимодействия с пользователем. Причин тому много, но одна из наиболее очевидных это то, что веб-формы - это самый простой способ для пользователя вводить информацию в приложение. В этой статье мы обсудим несколько методов, которые позволят вашим формам отвечать на ввод данных пользователя, а также помогут скрыть лишние непонятные или подавляющие элементы.
Давайте начнем!
Формы похожи на беседы
Представьте форму в виде разговора, который вы ведете с вашим пользователем. Из разговора становится понятно, что когда каждая сторона предлагает другой стороне ответить на вопрос. Например, предположим, что ваш пользователь приходит либо зарегистрироваться, либо подписаться. В обоих случаях вам нужна его электронная почта, так почему бы не начать диалог?
Дайте мне свой адрес электронной почты, и я проверю, есть ли у вас учетная запись. Если она существует, я попрошу вас ввести ваш пароль, либо вы создадите новый и подтвердите его.
Поэтому, когда пользователь приходит на страницу с формой, он видит четкий вопрос: «Какой у вас адрес электронной почты?»
Приставучий парень на вечеринке
Мы все знаем этого парня. Он тот парень, которого вы избегаете, потому что он без конца говорит какую-то ерунду, а сам даже не слушает, что вы скажете. Честно говоря, этот парень действительно нервирует окружающих, и я не уверен, что он кому-то нравится. Не хотелось бы быть этим парнем.
Однако, у него есть чему поучиться. Вместо того, чтобы противостоять вашему пользователю с большим количеством входов, подумайте об уменьшении рабочей нагрузки пользователя путем создания реактивных входов.
Давайте рассмотрим простой пример.
Форма входа
Процесс входа в систему выглядит примерно так: я ввожу свой адрес электронной почты, затем ввожу пароль, и нажимаю клавишу ввода. В этом примере вы узнаете, как показывать каждое из этих полей только после завершения предыдущего, используя только HTML и CSS. Мы создадим сначала её, а затем модифицируем версию.
Сделаем первую запись в нашей разметке.
1 |
<form method="post"> |
2 |
<input type="email" name="email" required> |
3 |
<input type="password" placeholder="Password..." required> |
4 |
<input type="submit"> |
5 |
</form>
|
Если это выглядит немного сложным, не волнуйтесь, я объясню каждую часть. Давайте начнем с ввода электронной почты. Мы видим несколько атрибутов, добавленных в тег за пределами имени. Прежде всего, тип ввода установлен на «email»; это относительно новый тип ввода, который дает нам определенное поведение в поддержке браузеров. Например, на iPhone символ «@» будет отображаться на основной клавиатуре.
Другая особенность типов ввода заключается в том, что формы HTML5 обладают способностью проверки данных на уровне браузера. Это означает, что вам не нужно писать JavaScript для выполнения проверки для элементов базовой формы!Обратите внимание, что у нас есть атрибут «обязательно» как для элемента электронной почты, так и для пароля. Как только эти два элемента будут заполнены, а их значения будут считаться корректными в браузере, вы можете даже настроить их с помощью псевдоселектора :valid
.
Область Регулярных Выражений
Это конечно здорово, но мы могли бы сделать всё еще лучше. Например, браузер принимает «a@b» в качестве подходящего адреса электронной почты. Причина этого в том, что адрес электронной почты можно настроить, чтобы получить что-то вроде «something@ localhost». Наш пароль может быть любым, поэтому пароль, состоящий из одного символа, такой как «a», также считается корректным. Давайте добавим регулярные выражения, чтобы исправить эти проблемы.
Примечание: если вы не знакомы с регулярными выражениями, это нормально! Мы их рассмотрим, чтобы показать, как вы можете использовать их для общих задач проверки формы на HTML5, но вы можете придерживаться реализаций проверки с помощью браузера и следовать руководству. Тогда просто пропустите этот раздел и продолжайте работу!
Еще одно примечение: вы также можете использовать Regular Expressions for Dummies: Screencast Series руководство для чайников: серию уроков Джеффри Пути.
1 |
<form method="post"> |
2 |
<input type="email" name="email" required pattern="[^ @]*@[^ @]*\.[a-zA-Z]{2,}"> |
3 |
<input type="password" placeholder="Password..." required pattern=".{5,}"> |
4 |
<input type="submit"> |
5 |
</form>
|
Давайте рассмотрим каждую часть этой модели. Регулярные выражения - это способ описания и сравнения формата строки.
Мы начнем с шаблона электронной почты.
1 |
pattern="[^ @]*@[^ @]*\.[a-zA-Z]{2,}" |
-
[^ @]*
- любые цифры и символы, которые не содержат знак @ или пустое пространство. -
@
- буквенное обозначение знака @ -
\.
- обозначение точки -
[a-zA-Z]
- любые символы верхнего или нижнего регистра -
[a-zA-Z]{2,}
- комбинация двух или более букв.
Соединив все это вместе, выражение информирует нас, что email представляет собой любой набор символов, за исключением знака @, за первой частью которого следует знак @ и любой набор символов, кроме знака @, далее за которым следует диапазон, в котором содержится по крайней мере две буквы.
Мы можем использовать более простое регулярное выражение, если хотим провести проверку, основываясь на длине значения:
1 |
pattern=".{5,}" |
.
означает «любой символ», а {5}
говорит, что этих символов должно быть не менее 5.
Используя эти примеры, элемент не будет считаться корректным до тех пор, пока не будет введено значение, удовлетворяющее условиям.
Мы завершаем разметку дополнительными корректировками и элементами.
1 |
<link href=’http://fonts.googleapis.com/css?family=Varela+Round’ rel=’stylesheet’ type=’text/css’> |
2 |
<div class="login"> |
3 |
<h3>Log In</h3> |
4 |
<form action="." method="post"> |
5 |
<input type="email" placeholder="Your Email" pattern="[^ @]*@[^ @]*\.[^ @]{2,}" required /> |
6 |
<input type="password" placeholder="Password..." required pattern=".{5,}" /> |
7 |
<input type="submit" /> |
8 |
</form>
|
9 |
</div>
|
Немного магии при помощи :valid
CSS
Теперь, когда у нас есть разметка для нашей формы входа, давайте посмотрим, что мы можем еще сделать, используя CSS, чтобы ответить на ввод данных пользователя.
Мы хотим отобразить следующий элемент формы, когда предыдущие данные введены корректно. Начнем с того, что скроем некоторые элементы, таким образом, чтобы пользователи могли видеть всю форму, и чтобы автозаполнение помогло пользователю ввести данные. (Крис Койер рассказывает о том, почему не следует использовать display:none
здесь.) Мы будем использовать метод visuallyhidden
, описанный в статье Криса.
1 |
.visuallyhidden { |
2 |
position: absolute; |
3 |
overflow: hidden; |
4 |
clip: rect(0 0 0 0); |
5 |
height: 1px; width: 1px; |
6 |
margin: -1px; padding: 0; border: 0; |
7 |
}
|
Мы начнем с некоторых основных стилей.
1 |
body { |
2 |
background-color: #245245; |
3 |
font-family: ’Varela Round’, sans-serif; |
4 |
}
|
5 |
h3 { |
6 |
color: #555; |
7 |
font-size: 2em; |
8 |
text-transform: uppercase; |
9 |
letter-spacing: .3em; |
10 |
}
|
11 |
.login { |
12 |
width: 300px; |
13 |
margin: 50px auto; |
14 |
background: #f5f9fa; |
15 |
padding: 50px; |
16 |
border-radius: 8px; |
17 |
text-align: center; |
18 |
}
|
19 |
|
20 |
input[type=password], |
21 |
input[type=email]{ |
22 |
width: 100%; |
23 |
border: 1px solid #ccc; |
24 |
padding: 8px; |
25 |
box-sizing: border-box; |
26 |
}
|
27 |
|
28 |
input[type=password]:focus, |
29 |
input[type=email]:focus { |
30 |
border: 1px solid #888; |
31 |
outline: none; |
32 |
}
|
33 |
input[type=submit] { |
34 |
background-color: #F29E1E; |
35 |
width: 50%; |
36 |
border: none; |
37 |
padding: 8px; |
38 |
box-sizing: border-box; |
39 |
color: #fff; |
40 |
font-family: "Varela Round"; |
41 |
font-size: 1em; |
42 |
text-transform: uppercase; |
43 |
}
|
44 |
input[type=submit]:hover { |
45 |
background-color: #DB8F2A; |
46 |
cursor: pointer; |
47 |
}
|
48 |
input { |
49 |
margin: 6px 0; |
50 |
}
|



Предлагаю использовать концепцию Криса. Применим ее к элементам, которые хотим скрыть.
1 |
input[type=password], |
2 |
input[type=submit]{ |
3 |
overflow: hidden; |
4 |
clip: rect(0 0 0 0); |
5 |
height: 1px; width: 1px; |
6 |
margin: -1px; padding: 0; border: 0; |
7 |
opacity: 0; |
8 |
transition: opacity 0.4s, height .4s, padding-top .4s, padding-bottom .4s; |
9 |
}
|



Мы создадим анимацию и немного расширим класс, чтобы включить непрозрачность, удалить абсолютное позиционирование, а также добавить определение точек плавного перехода.
Примечание. Здесь мы не добавили префиксы, необходимые для разных браузеров.
Теперь давайте отобразим их там где они должны быть используя псевдоселектор :valid
и селектор +
1 |
input[type=email]:valid + input[type=password]{ |
2 |
opacity: 1; |
3 |
position: relative; |
4 |
height: 30px; |
5 |
width: 100%; |
6 |
clip: none; |
7 |
margin: 12px auto; |
8 |
border: 1px solid #ccc; |
9 |
padding: 8px; |
10 |
}
|
11 |
input[type=password]:valid + input[type=submit]{ |
12 |
opacity: 1; |
13 |
position: relative; |
14 |
height: 40px; |
15 |
width: 50%; |
16 |
clip: none; |
17 |
margin: 12px auto; |
18 |
padding: 8px; |
19 |
}
|



Примечание о лучших примерах использования
Важно учитывать цели и ожидания пользователя, заполняющего веб-форму. Иногда хорошим решением будет полностью скрыть вход от пользователя. Однако в некоторых случаях заполнение формы может дать отрицательный эффект, и пользователь может почувствовать, что заполнение формы не имеет четкой последовательности и требует много времени, и это заставит его уйти со странички регистрации.
Хорошим решением этой проблемы было бы использование какого-то промежуточного состояния, без необходимости скрыть поле ввода, которое поможет создать пояснения и обратную связь для формы, в которой есть четкая цель и ожидаемая реакции. Вот модифицированная версия, которая использует масштабирование, фильтр размытия webkit, непрозрачность и параметр pointer-events:none
чтобы показать поля ввода пользователю, по мере их необходимости. Нам также необходимо убедиться, что pointer-events перезагрузится, когда поля ввода доступны для заполнения и пользователь мог бы нажать на них.



1 |
body { |
2 |
background-color: #245245; |
3 |
font-family: ’Varela Round’, sans-serif; |
4 |
}
|
5 |
h3 { |
6 |
color: #555; |
7 |
font-size: 2em; |
8 |
text-transform: uppercase; |
9 |
letter-spacing: .3em; |
10 |
}
|
11 |
.login { |
12 |
width: 300px; |
13 |
margin: 50px auto; |
14 |
background: #f5f9fa; |
15 |
padding: 50px; |
16 |
border-radius: 8px; |
17 |
text-align: center; |
18 |
}
|
19 |
|
20 |
input[type=password], |
21 |
input[type=email]{ |
22 |
width: 100%; |
23 |
border: 1px solid #ccc; |
24 |
padding: 8px; |
25 |
box-sizing: border-box; |
26 |
}
|
27 |
|
28 |
input[type=password]:focus, |
29 |
input[type=email]:focus { |
30 |
border: 1px solid #888; |
31 |
outline: none; |
32 |
}
|
33 |
|
34 |
input[type=submit] { |
35 |
background-color: #F29E1E; |
36 |
width: 50%; |
37 |
border: none; |
38 |
padding: 8px; |
39 |
box-sizing: border-box; |
40 |
color: #fff; |
41 |
font-family: "Varela Round"; |
42 |
font-size: 1em; |
43 |
text-transform: uppercase; |
44 |
}
|
45 |
input[type=submit]:hover { |
46 |
background-color: #DB8F2A; |
47 |
cursor: pointer; |
48 |
}
|
49 |
input { |
50 |
margin: 6px 0; |
51 |
}
|
52 |
|
53 |
input[type=password], |
54 |
input[type=submit]{ |
55 |
-webkit-filter: blur(1px); |
56 |
transform: scale(0.9); |
57 |
opacity: .4; |
58 |
transition: all .4s; |
59 |
pointer-events: none; |
60 |
}
|
61 |
|
62 |
input[type=password]:valid + input[type=submit], |
63 |
input[type=email]:valid + input[type=password] { |
64 |
pointer-events: auto; |
65 |
-webkit-filter: none; |
66 |
transform: scale(1); |
67 |
opacity: 1; |
68 |
}
|
Единственная ошибка, которую мы должны быстро исправить: это то, когда пользователь нажимает на вкладку, он собирается ввести следующий элементы формы. В нашей форме мы запретим это дополнительное действие с помощью pointer-events:none
, но в CSS нет атрибута «focusable». Вместо этого нам нужно будет управлять этим поведением с помощью JavaScript (с элементами jQuery).
1 |
var inputs = $("input"); |
2 |
$(document).on("keypress", "input", function(){ |
3 |
inputs.each(function(i,el){ |
4 |
var $el = $(el); |
5 |
if ($el.is(":valid")){ |
6 |
$el.next("input")[0].disabled=false; |
7 |
} else { |
8 |
$el.next("input")[0].disabled=true; |
9 |
} |
10 |
}); |
11 |
}); |
Этот код на JavaScript будет контролировать наши поля ввода и отключать / включать их на основе предыдущего состояния элемента «:valid» Это не позволит нам выделить элемент. pointer-events:none
все еще работает, и не позволяет нажать на нашу кнопку отправки.
Другие случаи использования
Представьте себе форму с несколькими «путями», как в нашем примере «вход в систему или регистрация». Пользователь может выбирать несколько параметров, которые потребуют ввода дополнительной информации, например выбор способа доставки или время бронирования столика. В этих случаях простой проверки может быть недостаточной, и вместо этого мы будем использовать JavaScript решения.
Возьмем, к примеру, выбор входа в систему или регистрации. Для этого мы должны отправить запрос на сервер, существует ли пользователь с указанным адресом электронной почты.
1 |
<form action=""> |
2 |
<input type="email"> |
3 |
<input name="login_password" type="password"> |
4 |
<input name="signup_password" type="password"> |
5 |
<input name="signup_password_confirm" type="password"> |
6 |
</form>
|
1 |
var timeout; |
2 |
$(document).on("keyup", "input[type=email]" function(){ |
3 |
clearTimeout(timeout); |
4 |
var input = $(this); |
5 |
timeout = setTimeout(function(){ |
6 |
if (input.is(":valid")){ |
7 |
var email = input.val(); |
8 |
$.getJSON("/check_for_user", {email : email}, function(data){ |
9 |
if (data.user_exists){ |
10 |
input.parents("form").attr("action","/login") |
11 |
input.addClass("user_exists"); |
12 |
$("input[type=password]").filter("[name*=’login’]").each(function(i,el){ |
13 |
el.required = true; |
14 |
}) |
15 |
} else { |
16 |
input.parents("form").attr("action","/sign_up") |
17 |
input.addClass("user_not_exists"); |
18 |
$("input[type=password]").filter("[name*=’signup’]").each(function(i,el){ |
19 |
el.required = true; |
20 |
}) |
21 |
} |
22 |
}); |
23 |
} |
24 |
}) |
25 |
}); |
В приведенном выше примере на JavaScript мы отправляем адрес электронной почты на сервер по URL-адресу / check_for_user. Сервер вернет простой ответ в формате JSON, похожий на следующий.
1 |
callback({ |
2 |
user_exists : true |
3 |
}); |
Основываясь на этом значении, мы присвоим класс к полю ввода и изменим пункт направления для данных формы. Мы также устанавливаем пароли, которые будут проверены на соответствие. Затем мы могли бы использовать CSS различными способами, чтобы определить, что будет дальше. Например, мы могли бы использовать аналогичный подход, указанный ранее, чтобы показать или скрыть поля ввода.
Если вы регистрируете новую учетную записи, нам нужно поле для ввода пароля (это не поле пароля, которое мы использовали для входа ). Для этого мы будем использовать селектор ~
, который является общим селектором для дочерних элементов и позволит нам «обойти» неподходящие.
1 |
input[name="signup_password"] { |
2 |
/* visually hidden styles here */
|
3 |
}
|
4 |
input[type=email].user_not_exists:valid ~ input[name="signup_password"] { |
5 |
/* "visible" styles go here */
|
6 |
}
|
7 |
input[type=email].user_exists:valid ~ input[name="login_password"] { |
8 |
/* "visible" styles go here */
|
9 |
}
|
Ответы
Когда мы публикуем новые приемы разработки интерфейса, они могут не работать во всех браузерах. К счастью, с этой проблемой легко справиться. Большинство браузеров справятся с этим, но к сожалению, сюда нельзя отнести iOS 7 или Android. Для них мы просто установим поведение формы по умолчанию.
Для этого мы будем использовать скрипт Modernizr, чтобы определить поддерживает ли браузер проверку элементов формы. Лучше всего использовать Modernizr для обнаружения этих возможностей, но мы можем и самостоятельно написать данную функцию. В «Non-Core Detect» от Modernizr включен параметр «forms-validation», поэтому вам нужно будет создать свои настройки библиотеки. После того, как вы установите ее, во всех браузерах, который их поддерживает, к элементу html
будет присвоен класс form validation
. Вы можете настроить форму, которая будет улучшена с помощью класса formvalidation
для поддерживаемых браузеров.
1 |
.formvalidation input[type=password], .formvalidation input[type=submit] { |
2 |
/* Hide or obscure your inputs and disable pointer-events here */
|
3 |
}
|
Так как мы знаем, что элементы :valid
и :invalid
будут работать в поддерживаемых браузерах, CSS, который скрывает поля ввода единственный CSS, который нам нужно, для того чтобы использовать с современными расширениями. Поля ввода будут выполнять функцию по умолчанию в тех браузерах, которые не поддерживают эти приемы.
Вот так вот!
Теперь у вас есть отличные способы, чтобы вывести ваши формы на новый уровень интерактивного взаимодействия с вашими пользователями. Какие еще сильные стороны вы можете представить, используя псевдо классы :valid
и :invalid
? Поговорим об этом в комментариях!