Поле ввода HTML — простой и удобный элемент. Оно содержит более 30 вариантов атрибутов и является одним из самых надежных и заслуживающих изучения HTML-тегов. Поскольку пользователи постоянно взаимодействуют с полями на странице, приходится прилагать множество усилий, чтобы сделать их максимально удобными. Однако по ходу дела могут возникнуть различные сложности.

Базовая разметка
Помечать поля — отличная CSS-практика. В статье мы будем использовать вложенное поле внутри разметки метки, которое связывает метку и входной тег и устраняет необходимость указывать атрибут for
для метки и id
для ввода. К тому же это значительно упрощает стилизацию поля.
<label class="custom-field">
<input type="email"/>
<span class="placeholder">Enter Email</span>
</label>
Другой альтернативой может послужить тег div
в качестве обертки для таких элементов, как позиционирование, чтобы у них был общий родитель. Тег fieldset
также может быть полезен в некоторых случаях. Данный метод позволяет расположить метку и ввод рядом и рассматривать их как единое целое.
<div class="custom-field">
<input id="email-field" type="email"/>
<label for="email-field" class="placeholder">Enter Email</label>
</div>
Еще более короткая и допустимая альтернатива — использовать тег label
с полем ввода внутри, но с атрибутом aria-label
для читателей экрана, а затем применить псевдоэлемент CSS after
для создания заполнителя.
<label class="custom-field" aria-label="Enter Email">
<input type="email"/>
</label>
// Создание заполнителя
.custom-field::after {
content: attr(aria-label);
}
Все три альтернативы подойдут для типа стиля, который будет использоваться в данной статье, поэтому выберите любой из них по своему предпочтению. Ниже показано, что все три параметра отображают одно и то же на странице. Результат отображен в браузере Chrome.

Для чего мы ставим метку после ввода? Данный шаг дает возможность использовать такие состояния ввода, как focus
и т. д. Таким образом мы сможем настроить метку и контролировать ее внешний вид и анимацию. В качестве альтернативы можно использовать Javascript, но это выходит за рамки данного руководства.
Начальная настройка
Если вы не используете CSS-нормализаторы, вам все же стоит добавить такие элементы CSS, как border-box
и box-sizing
— они важны для данного руководства. Если в конечном итоге готовое поле выглядит не так, как в статье, то, скорее всего, вам понадобится следующий фрагмент кода:
*, *::before, *::after {
box-sizing: border-box;
}
Базовый стиль
Придадим данной области очень простой и минималистичный вид. Мы cможем улучшить его по ходу работы.

Для этого поля размер текста составит 14 пикселей. Элемент placeholder
будет располагаться над полем ввода, поэтому необходимо установить относительное (relative
) положение.
.custom-field {
font-size: 14px;
position: relative;
}
Стиль поля ввода в основном предназначен для его сброса, например для удаления внешнего вида и границ. Обратите внимание, что ширина поля ввода определяет размер элемента custom-field
. Следующей важной деталью здесь является заполнение, которое нужно сопоставить при размещении элемента-заполнителя наверху.
.custom-field input {
border: none;
-webkit-appearance: none;
-ms-appearance: none;
-moz-appearance: none;
appearance: none;
background: #f2f2f2;
padding: 12px;
border-radius: 3px;
width: 250px;
font-size: 14px;
}
Мы расположили заполнитель слева от 12 пикселей, чтобы он соответствовал заполнению ввода. Мы также использовали преобразование для выравнивания по вертикали -50% с верхней частью — 22 пикселя. Такое количество пикселей необходимо для создания идеально центрированного преобразования. Верхняя часть 50% также работает, но из-за сообщения об ошибке мы используем пиксели.
Чтобы текст заполнителя не был слишком длинным, ограничиваем его ширину максимальным 100%-значением минус 24 пикселя (сумма входных левых и правых отступов). Затем устанавливаем переполнение в виде многоточия.
.custom-field .placeholder {
position: absolute;
left: 12px;
bottom: 50%;
top: 22px;
transform: translateY(-50%);
width: calc(100% - 24px);
color: #aaa;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Вы можете использовать переменную CSS, но, если вы измените заполнение ввода позже, это также повлияет на заполнитель.
.custom-field {
...
--field-padding: 12px;
}
.custom-field input {
...
padding: var(--field-padding);
}
.custom-field .placeholder {
...
left: var(--field-padding);
width: calc(100% - (var(--field-padding) * 2));
}
Эффект всплывающей метки
Если нажать на поле, заполнитель уменьшиться и переместится в верхний левый угол над полем.

Чтобы добавить этот переход, нужно обозначить пространство над полем, куда будет перемещаться заполнитель. Оно также пригодится, если перед полем появится другой элемент. 20 пикселей на верхней границе — отличный вариант: метка остается центрированной, а граница выступает внешней частью.
.custom-field {
...
border-top: 20px solid transparent;
}
Далее нужно узнать, когда ввод получает фокус, чтобы анимировать заполнитель. Воспользуемся сиблинг-комбинатором, чтобы выбрать заполнитель, а затем уменьшить шрифт, установить темный цвет и поднять его на 10 пикселей.
.custom-field input:focus + .placeholder {
top: -10px;
font-size: 10px;
color: #222;
}
При наличии значения заполнитель должен оставаться в таком положении, даже если фокус отсутствует. Достичь этой цели можно несколькими способами. Например, использовать псевдокласс ввода :valid
вместе с атрибутом required
. Однако стоит учитывать, что это работает только для обязательных полей.
<input type="email" required/>
// Если обязательное поле допустимо, значит оно имеет значение
// Если указано большое количество правил подтверждения, то это может привести к нарушению ввода: valid + .placeholder {
...
}
Другой альтернативой является использование Javascript для определения класса, вне зависимости от наличия значения. Однако данное руководство предназначено только для CSS, поэтому laceholder-shown
вместе с атрибутом заполнителя может послужить отличным решением.
// Заполнитель НЕ должен быть пуст,
// чтобы этот метод сработал,
// а - просто пустое пространство
<input type="email" placeholder=" "/>
// Если заполнитель не отображается,
// значит, пользователь начал вводить значение ввода: not(:placeholder-shown) + .placeholder {
...
}
Чтобы получить хорошую анимацию, можно добавить переход наверх, размер шрифта и цвет в элемент-заполнитель.
.custom-field .placeholder {
...
transition:
top 0.3s ease,
color 0.3s ease,
font-size 0.3s ease;
}
.custom-field input:not(:placeholder-shown) + .placeholder
.custom-field input:focus + .placeholder {
top: -10px;
font-size: 10px;
color: #222;
}
Отображение сообщения об ошибке
В зависимости от формы, вам может потребоваться отобразить сообщение об ошибке. Для тега метки можно включить другой элемент для ошибки.

<label class="custom-field">
<input type="email" placeholder=" "/>
<span class="placeholder">Enter Email</span>
<span class="error-message" aria-live="polite"></span>
</label>
.custom-field {
...
margin-bottom: 24px;
}
.custom-field .error-message {
width: 100%;
display: flex;
align-items: center;
padding: 0 8px;
font-size: 12px;
background: #d30909;
color: #fff;
height: 24px;
}
.custom-field .error-message:empty {
opacity: 0;
}
Важно помнить, что поле ошибки по ширине равно полю ввода и располагается под ним. Вы также можете проверить наличие ошибки и отобразить элемент сообщения об ошибке.
Вежливое значение показывает то, как следует сообщить пользователю об ошибке. Для данного сценария необходим такой атрибут, чтобы помочь с текстом mix ox внутри тега label.
Вывод
Данные техники можно применять для создания полей, при этом не затрагивая доступность и SEO. Разобраться в них более подробно вам поможет исходный код.
А в этом ролике представлена информация о стилизации полей ввода.
Читайте также:
- 12 ошибок начинающих веб-разработчиков
- Основные принципы кэширования веб-приложений
- Краткая история инструментов веб-дизайна
Читайте нас в Telegram, VK и Дзен
Перевод статьи Before Semicolon: How to Style any Input Field — Tips and Technique