Выпрыгивающий из текстового поля placeholder
и переходящий в его подпись (label
) выглядит эффектно и давно применяется в веб-формах. Существует множество вариаций этого эффекта, но принцип реализации у них схожий. Когда поле ввода текста пустое, его подпись placeholder
размещается внутри и подсказывает пользователям, какое ожидается значение. Как только input
получает фокус, placeholder
выскакивает наружу, масштабируется и трансформируется в label
. Теперь его назначение – напоминать, какую информацию уже ввел пользователь, а не подсказывать, что ожидалось для ввода в поле.
Эта техника – пример прогрессивного UX, когда подписи к полям формы утрачивают важность по мере того, как пользователь продолжает заполнять форму. Утрачивающие по ходу взаимодействия с пользователем важность элементы уходят на второй план, а новые и актуальные перемещаются на передний план.
В этой статье рассматривается пример с использованием “прыгающих” текстовых подписей к полям формы. Для примера используется форма регистрации, где placeholder
выпрыгивают из input
и попадают в кармашки над ними, становясь label
.
Рассуждения о семантике
Всю HTML-разметку веб-страницы можно сделать с помощью только <div>… </div>
. Это легко и часто даже как-то работает. По ситуации div
легко стилизовать и получить результат, который будет выглядеть приемлемо. Но такой способ работы обманчив. Многие вещи не будут работать нормально. В частности, у таких веб-страниц будут серьёзные проблемы с доступностью. Многие функции доступности встроены в HTML и работают “из коробки” при правильном применении HTML-элементов. Но если их использовать не по назначению, например заменить кнопки и метки абстрактными элементами, типа div
, браузер не получит достаточного представления об их использовании и назначении. Программы чтения с экрана и другие вспомогательные инструменты не смогут правильно интерпретировать эти элементы.
Это плохо не только для доступности, но и для самой HTML-разметки, состоящей из элементов одинакового типа, например, из одних div
. Поначалу с этим ещё можно справляться, но по мере развития кода, отсутствие семантики в разметке доставит немало проблем с его поддержкой и расширением. Поэтому следует использовать правильные HTML-элементы в правильном контексте, т.е. в соответствии с их назначением. Так можно бесплатно получить много готовых решений и обойтись без изобретения велосипедов.
В случае с текстовыми полями и метками к ним, для обоих есть соответствующие HTML-элементы: input
и label
. У HTML-элемента label
есть атрибут for
, который позволяет связать метку и текстовое поле input
. Вот как это выглядит в коде:
<input id="firstname" class="input" type="text" placeholder=" " />
<label for="firstname" class="placeholder">First name</label>
Пробел в значении атрибута
placeholder
– трюк, позволяющий для управления логикой фокуса использовать только CSS.
Обнаружение изменений при вводе текста
Атрибут placeholder
у поля формы позволяет использовать CSS-правило :placeholder-shown
. Тогда только с помощью CSS и без Javascript, можно легко определить, есть ли в input
значение. Когда значение атрибута placeholder
текстового input
должно быть видимым, в текстовом поле (из примера кода выше) будет показываться прозрачный пробел. Если браузер показывает содержимое из placeholder
, точно известно, что у input
нет значения, т.е. поле не заполнено.
После ввода в текстовое поле текста браузер автоматически скрывает его placeholder
. Это не будет заметно, поскольку в нём используется прозрачный пробел. Зато технически теперь у текстового поля есть значение, а браузер переключил отображаемое состояние подсказки (placeholder
). Это состояние позволяет CSS управлять другими элементами в зависимости от того, есть ли в текстовом поле input
какое-нибудь значение или нет.
Для того, чтобы добавить эффектный прыжок подсказки из поля наружу, нужны следующие условия:
- Фокус помещён в текстовом поле
- У
input
есть какое-то значение. Это рассмотренный выше случай, когда скрываетсяplaceholder
.
Вот как написать эти условия в CSS:
.input:focus ~ .label, /* фокус на input */
.input:not(:placeholder-shown) ~ .label /* в input есть значение */ {
transform: translateY(-30px) translateX(10px) scale(0.75);
}
Фрагмент CSS устанавливает стиль подписи-метки в зависимости от состояния текстового поля. Селектор ~
– это то, что соединяет input
и следующий после него в HTML-коде label
и расположенный на том же уровне. Когда это CSS-правило становится активным, подпись к полю меняет свой внешний вид: перемещается и масштабируется. Т.е. покидает поле ввода и не мешает пользователю печатать в нём.
Чтобы оживить переход состояния метки, можно добавить такой переход.
.label {
...
transition: transform 200ms, color 200ms;
...
}
Лучше этот переход разделить на два и таким образом выделять метку, когда фокус переместится в поле ввода текста. Всегда полезно дать пользователю визуальную подсказку о том, где находятся курсор и фокус. Курсор во многих случаях слишком тонкий, поэтому уделить больше внимания тому факту, что фокус перемещен в поле для ввода не повредит.
.input:not(:placeholder-shown) ~ .label {
color: #808097; /* сероватый */
}
.input:focus ~ .label {
color: #dc2f55; /* красный, фокус в поле */
}
Кармашки для меток
Для кармашков подойдут контейнеры со скругленными углами того же цвета, что и фон.
На картинке для наглядности цвет контейнеров-кармашков показан ярким и четким. Он иллюстрирует форму HTML-узлов, которые для этого используются.
Может показаться излишним использовать два элемента для label
и его подложки вместо того, что окажется одним. Однако так будет проще нарисовать кармашек поверх существующей разметки и добавить ему какие-нибудь трансформации для эффектного появления.
Тогда для перемещения кармашка-подложки можно использовать точно такую же логику трансформации как для текста. Единственное отличие состоит в том, что контейнер со скругленными углами по вертикали перемещается в противоположном направлении навстречу тексту.
.input:focus ~ .pocket,
.input:not(:placeholder-shown) ~ .pocket {
transform: translateY(8px);
}
Пример
В заключение
Лёгкая анимация элементов формы в ответ на действия пользователя усиливает ощущение ответной реакции, а перемещение подсказок в ответ на изменение состояния поля ввода – хороший пример прогрессивного UX.
Чтобы определить, когда нужно активировать анимацию используется только CSS.
Для демонстрации перемещения подписи-метки поля ввода формы, использован CSS-transition для translate
и scale
.