Выпрыгивающий из текстового поля 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 какое-нибудь значение или нет.

:placeholder-shownДля того, чтобы добавить эффектный прыжок подсказки из поля наружу, нужны следующие условия:
- Фокус помещён в текстовом поле
- У
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; /* красный, фокус в поле */
}
Кармашки для меток
Для кармашков подойдут контейнеры со скругленными углами того же цвета, что и фон.

labelНа картинке для наглядности цвет контейнеров-кармашков показан ярким и четким. Он иллюстрирует форму HTML-узлов, которые для этого используются.
Может показаться излишним использовать два элемента для label и его подложки вместо того, что окажется одним. Однако так будет проще нарисовать кармашек поверх существующей разметки и добавить ему какие-нибудь трансформации для эффектного появления.
Тогда для перемещения кармашка-подложки можно использовать точно такую же логику трансформации как для текста. Единственное отличие состоит в том, что контейнер со скругленными углами по вертикали перемещается в противоположном направлении навстречу тексту.
.input:focus ~ .pocket,
.input:not(:placeholder-shown) ~ .pocket {
transform: translateY(8px);
}
Пример
В заключение
Лёгкая анимация элементов формы в ответ на действия пользователя усиливает ощущение ответной реакции, а перемещение подсказок в ответ на изменение состояния поля ввода – хороший пример прогрессивного UX.
Чтобы определить, когда нужно активировать анимацию используется только CSS.
Для демонстрации перемещения подписи-метки поля ввода формы, использован CSS-transition для translate и scale.



