Стилизация input css: как оформить поля формы
Стилизация input css помогает привести поля формы к единому виду без JavaScript. Вы зададите базовую геометрию, оформите состояния, select, чекбоксы, range, файл и кнопку. Отдельный раздел покажет, как применить эти правила к Gravity Forms в WordPress.
- Сброс и базовые стили полей
- Текстовые поля и плейсхолдер
- Состояния полей: hover, focus-visible, disabled, ошибка и автозаполнение
- Выпадающий список select со своей стрелкой
- Чекбоксы и радиокнопки: accent-color и полностью свой вид
- Ползунок range
- Поле загрузки файла
- Кнопка отправки
- Стили форм Gravity Forms в WordPress
- Ошибки при стилизации полей формы
Сброс и базовые стили полей
Ограничьте сброс классом формы.
Так правила не изменят поиск, авторизацию и другие формы сайта.
<form class="form-ui" method="post" enctype="multipart/form-data">
<div class="field">
<label for="email">Электронная почта</label>
<input id="email" name="email" type="email" autocomplete="email" required>
</div>
<button type="submit">Отправить</button>
</form>.form-ui,
.form-ui *,
.form-ui *::before,
.form-ui *::after {
box-sizing: border-box;
}
.form-ui {
--accent: #1d4ed8;
--border: #64748b;
--error: #b91c1c;
display: grid;
gap: 1.25rem;
max-width: 34rem;
margin: 2rem auto;
padding: 1rem;
color: #172033;
background: #fff;
font: 1rem/1.5 system-ui, sans-serif;
}
.form-ui :is(input, select, textarea, button) {
font: inherit;
}
.form-ui .field {
display: grid;
gap: 0.375rem;
min-width: 0;
}
.form-ui label {
font-weight: 600;
}
.form-ui :where(
input:not([type]),
input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="time"],
select,
textarea
) {
display: block;
width: 100%;
min-width: 0;
min-height: 2.75rem;
padding: 0.625rem 0.75rem;
border: 1px solid var(--border);
border-radius: 0.375rem;
background: #fff;
color: #172033;
}
.form-ui :is(input, select, textarea, button):focus-visible {
outline: 3px solid var(--accent);
outline-offset: 3px;
}box-sizing: border-box включает рамку и отступы в ширину элемента. Свойство font: inherit передает полям шрифт формы, а переменные собирают цвета в одном месте.
Не задавайте общую ширину голому селектору input. Такое правило заденет чекбоксы, radio и range, которым нужны другие размеры.
Normalize.css и modern-normalize выравнивают базовые различия браузеров. Подключайте один вариант перед собственными правилами, но все равно задавайте стили формы отдельно.
Текстовые поля и плейсхолдер
Постоянная подпись объясняет назначение поля после очистки.
Свяжите ее с элементом через одинаковые значения for и id.
<div class="field">
<label for="person-name">Имя</label>
<input id="person-name" name="person_name" type="text"
autocomplete="given-name" placeholder="Анна">
</div>
<div class="field">
<label for="message">Сообщение</label>
<textarea id="message" name="message" rows="4"
placeholder="Опишите задачу"></textarea>
</div>.form-ui :is(input, textarea)::placeholder {
color: #64748b;
opacity: 1;
}
.form-ui textarea {
min-height: 8rem;
resize: vertical;
}Псевдоэлемент ::placeholder меняет подсказку внутри поля. Значение opacity: 1 убирает дополнительную прозрачность.
Свойство resize: vertical оставляет пользователю изменение высоты textarea.
Плейсхолдер показывает пример, но не заменяет label.
Состояния полей: hover, focus-visible, disabled, ошибка и автозаполнение
Состояния должны объяснять, что происходит с полем. Разделяйте наведение, фокус, недоступность и ошибку.
Наведение, фокус и отключенное поле
Добавляйте hover только устройствам с указателем. Сенсорный экран не получает случайное состояние наведения.
@media (hover: hover) {
.form-ui :is(input, select, textarea):enabled:hover {
border-color: var(--accent);
}
}
.form-ui :is(input, select, textarea, button):disabled {
background-color: #e2e8f0;
color: #475569;
cursor: not-allowed;
opacity: 1;
}Псевдокласс :enabled исключает отключенные элементы из hover. Атрибут disabled запрещает взаимодействие и исключает значение из отправки.
Не удаляйте outline без замены.
Общее правило :focus-visible выше оставляет заметный фокус при навигации клавиатурой.
Ошибка после взаимодействия и ответ сервера
Селектор :invalid способен подсветить пустое обязательное поле сразу. Для ошибки после действия пользователя используйте :user-invalid, если его поддерживает браузер.
@supports selector(:user-invalid) {
.form-ui :is(input, select, textarea):user-invalid {
border-color: var(--error);
border-width: 2px;
}
}
.form-ui :is(input, select, textarea)[aria-invalid="true"] {
border-color: var(--error);
border-width: 2px;
}
.form-ui .field-error {
margin: 0;
color: var(--error);
}<div class="field">
<label for="account-email">Почта учетной записи</label>
<input id="account-email" name="account_email" type="email"
aria-invalid="true" aria-describedby="account-email-error">
<p id="account-email-error" class="field-error">
Эта почта уже привязана к учетной записи.
</p>
</div>Серверная ошибка получает aria-invalid="true". Атрибут aria-describedby связывает поле с пояснением ошибки.
После исправления сервер убирает атрибут и сообщение.
CSS показывает состояние, но не проверяет данные формы.
Автозаполнение браузером
Автозаполнение может менять фон и цвет текста. Оформите это состояние отдельно через :autofill.
@supports selector(input:autofill) {
.form-ui input:autofill {
border-color: var(--accent);
border-style: dashed;
}
}Оставьте автозаполнение включенным: оно сокращает ручной ввод и помогает пользователям, которые работают с клавиатурой.
Выпадающий список select со своей стрелкой
Для закрытого однострочного списка можно заменить системную стрелку SVG-иконкой. Списки с multiple и size сохраните в нативном виде.
.form-ui select:not([multiple]):not([size]) {
appearance: none;
padding-right: 2.75rem;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='m4 6 4 4 4-4' fill='none' stroke='%23334155' stroke-width='2'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.875rem center;
background-size: 1rem 1rem;
}
@media (forced-colors: active) {
.form-ui select:not([multiple]):not([size]) {
appearance: auto;
background-image: none;
}
}appearance: none убирает системную стрелку. Правый отступ оставляет место для SVG, а %23 кодирует решетку внутри data URI.
Режим принудительных цветов возвращает системный вид. Так пользователь сохраняет контраст и узнаваемое управление.
CSS закрытого select не меняет все части всплывающего меню.
Подробности о свойстве appearance смотрите в справке MDN.
Чекбоксы и радиокнопки: accent-color и полностью свой вид
Выберите один из двух подходов по задаче дизайна. accent-color сохраняет нативное управление, а appearance: none дает контроль над индикатором.
Нативный вид с accent-color
Оставьте input в разметке и свяжите его с label. У radio одной группы должно быть одинаковое значение name.
<div class="choice">
<input id="updates" name="updates" type="checkbox" value="yes">
<label for="updates">Получать новости</label>
</div>
<fieldset class="choice-group">
<legend>Способ связи</legend>
<div class="choice">
<input id="contact-email" name="contact" type="radio" value="email">
<label for="contact-email">Электронная почта</label>
</div>
<div class="choice">
<input id="contact-phone" name="contact" type="radio" value="phone">
<label for="contact-phone">Телефон</label>
</div>
</fieldset>.form-ui .choice {
display: flex;
align-items: flex-start;
gap: 0.625rem;
}
.form-ui .choice input {
flex: 0 0 auto;
width: 1.25rem;
height: 1.25rem;
margin: 0.125rem 0 0;
accent-color: var(--accent);
}
.form-ui .choice-group {
display: grid;
gap: 0.625rem;
min-width: 0;
margin: 0;
padding: 0.75rem;
border: 1px solid var(--border);
}
.form-ui .choice input:disabled + label {
color: #64748b;
}Свойство accent-color меняет основной цвет нативного индикатора. Браузер продолжает рисовать галочку, кружок и состояния элемента.
Клик по label переключает элемент.
Пробел меняет чекбокс, а стрелки перемещают выбор внутри группы radio.
Собственный индикатор с appearance: none
Добавьте класс custom-choice к обертке. Input остается в потоке, поэтому Tab и пробел продолжают работать.
<div class="choice custom-choice">
<input id="updates-custom" name="updates-custom" type="checkbox" value="yes">
<label for="updates-custom">Получать новости</label>
</div>
<div class="choice custom-choice">
<input id="contact-custom-email" name="contact-custom" type="radio" value="email">
<label for="contact-custom-email">Электронная почта</label>
</div>.form-ui .custom-choice input {
appearance: none;
position: relative;
flex: 0 0 auto;
width: 1.25rem;
height: 1.25rem;
margin: 0.125rem 0 0;
padding: 0;
border: 2px solid var(--border);
border-radius: 0.25rem;
background: #fff;
}
.form-ui .custom-choice input[type="radio"] {
border-radius: 50%;
}
.form-ui .custom-choice input:checked {
border-color: var(--accent);
background: var(--accent);
}
.form-ui .custom-choice input:checked::before {
content: "";
position: absolute;
inset: 0.2rem;
border-right: 2px solid #fff;
border-bottom: 2px solid #fff;
transform: rotate(45deg) scale(0.7);
}
.form-ui .custom-choice input[type="radio"]:checked::before {
inset: 0.25rem;
border: 0;
border-radius: 50%;
background: #fff;
transform: none;
}
.form-ui .custom-choice input:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 3px;
}
@media (forced-colors: active) {
.form-ui .custom-choice input {
appearance: auto;
}
.form-ui .custom-choice input::before {
content: none;
}
}Селекторы совпадают с HTML-примером, поэтому блок можно копировать целиком. Не скрывайте input через display: none, потому что такой элемент исчезает из клавиатурного управления.
Ползунок range
Ползунок состоит из трека и бегунка. Chromium и Safari используют WebKit-псевдоэлементы, Firefox – Mozilla-псевдоэлементы.
<div class="field">
<label for="volume">Громкость от 0 до 100</label>
<input id="volume" name="volume" type="range" min="0" max="100" step="1" value="50">
</div>.form-ui input[type="range"] {
appearance: none;
display: block;
width: 100%;
height: 2rem;
margin: 0;
padding: 0;
border: 0;
background: transparent;
cursor: pointer;
}
.form-ui input[type="range"]::-webkit-slider-runnable-track {
height: 0.375rem;
border-radius: 1rem;
background: #64748b;
}
.form-ui input[type="range"]::-webkit-slider-thumb {
appearance: none;
width: 1.5rem;
height: 1.5rem;
margin-top: -0.5625rem;
border: 2px solid #fff;
border-radius: 50%;
background: var(--accent);
}
.form-ui input[type="range"]::-moz-range-track {
height: 0.375rem;
border-radius: 1rem;
background: #64748b;
}
.form-ui input[type="range"]::-moz-range-thumb {
box-sizing: border-box;
width: 1.5rem;
height: 1.5rem;
border: 2px solid #fff;
border-radius: 50%;
background: var(--accent);
}
.form-ui input[type="range"]:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 3px;
}
.form-ui input[type="range"]:disabled {
cursor: not-allowed;
opacity: 0.6;
}Высота трека равна 0,375 rem, а диаметр бегунка – 1,5 rem. Отрицательный margin-top центрирует бегунок WebKit.
Псевдоэлементы ::-webkit-slider-thumb и ::-moz-range-thumb сохраняют нужные префиксы.
Префиксы IE и устаревшие свойства добавлять не нужно.
Поле загрузки файла
Псевдоэлемент ::file-selector-button оформляет кнопку внутри нативного поля. Имя выбранного файла остается под управлением браузера.
<div class="field">
<label for="attachment">Приложение к сообщению</label>
<input id="attachment" name="attachment" type="file" aria-describedby="attachment-help">
<small id="attachment-help">Выберите документ для задачи.</small>
</div>.form-ui input[type="file"] {
display: block;
width: 100%;
min-width: 0;
padding: 0.375rem;
border: 1px solid var(--border);
border-radius: 0.375rem;
background: #fff;
color: #172033;
}
.form-ui input[type="file"]::file-selector-button {
margin-right: 0.75rem;
padding: 0.5rem 0.75rem;
border: 0;
border-radius: 0.25rem;
background: #e2e8f0;
color: #172033;
font: inherit;
cursor: pointer;
}
.form-ui input[type="file"]:disabled::file-selector-button {
background: #e2e8f0;
color: #64748b;
cursor: not-allowed;
}margin-right отделяет кнопку от имени файла. Свойство font: inherit выравнивает ее текст с остальной формой.
Для передачи файла оставьте у формы method="post" и enctype="multipart/form-data".
CSS меняет внешний вид, но не отправляет файл на сервер.
Кнопка отправки
Укажите кнопке явный тип и текст действия. Ограничьте правило классом формы, чтобы не изменить остальные кнопки сайта.
.form-ui button[type="submit"] {
justify-self: start;
min-height: 2.75rem;
padding: 0.625rem 1.25rem;
border: 2px solid transparent;
border-radius: 0.375rem;
background: var(--accent);
color: #fff;
font-weight: 700;
cursor: pointer;
}
@media (hover: hover) {
.form-ui button[type="submit"]:enabled:hover {
background: #1e40af;
}
}
.form-ui button[type="submit"]:enabled:active {
background: #1e3a8a;
}
.form-ui button[type="submit"]:disabled {
background: #e2e8f0;
color: #475569;
cursor: not-allowed;
}Постоянная прозрачная рамка сохраняет размер кнопки между состояниями. Общее правило :focus-visible добавляет видимый фокус.
Добавьте required к полю почты и отправьте пустую форму. Браузер остановит отправку и покажет встроенную подсказку.
Стили форм Gravity Forms в WordPress
Gravity Forms выводит собственную разметку.
Ограничьте CSS идентификатором одной формы, чтобы правила не затронули остальные формы WordPress.
Куда добавить CSS и как выбрать форму
Откройте страницу с формой и инструменты разработчика браузера. Выберите поле и найдите внешний контейнер с классом gform_wrapper и идентификатором формы.
- Скопируйте значение
idвнешнего контейнера. - Добавьте CSS в
style.cssдочерней темы или в область дополнительных стилей темы. - Замените
#gform_wrapper_1в примере идентификатором своей формы. - Сохраните CSS и обновите страницу с формой.
Если поля получили новые рамки и шрифт, селектор работает. Чтобы вернуть прежнее оформление, удалите добавленный блок CSS.
#gform_wrapper_1,
#gform_wrapper_1 *,
#gform_wrapper_1 *::before,
#gform_wrapper_1 *::after {
box-sizing: border-box;
}
#gform_wrapper_1 :is(input, select, textarea, button) {
font: inherit;
}
#gform_wrapper_1 :is(
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
textarea,
select
) {
width: 100%;
min-width: 0;
min-height: 2.75rem;
padding: 0.625rem 0.75rem;
border: 1px solid #64748b;
border-radius: 0.375rem;
background: #fff;
color: #172033;
}
#gform_wrapper_1 :is(input, select, textarea, button):focus-visible {
outline: 3px solid #1d4ed8;
outline-offset: 3px;
}
#gform_wrapper_1 :is(input[type="checkbox"], input[type="radio"]) {
accent-color: #1d4ed8;
}
#gform_wrapper_1 :is(input[type="submit"], button[type="submit"]) {
min-height: 2.75rem;
padding: 0.625rem 1.25rem;
border: 2px solid transparent;
border-radius: 0.375rem;
background: #1d4ed8;
color: #fff;
font-weight: 700;
cursor: pointer;
}Как уточнить селектор по классам поля
В текущей разметке Gravity Forms встречаются gfield, классы вида gfield--type-* и контейнеры ginput_container_*. Используйте их для точечного правила.
#gform_wrapper_1 .gfield--type-multiselect select {
background-image: none;
}
#gform_wrapper_1 select[multiple] {
min-height: 8rem;
background-image: none;
}Селектор select[multiple] работает по атрибуту. Идентификатор формы делает правило специфичнее общих правил плагина.
Когда отключать стили плагина
Отключайте встроенный CSS только после подготовки собственных правил для сетки, отступов, ошибок и составных полей. Откройте официальную документацию Gravity Forms и найдите актуальный способ отключения CSS для установленной версии.
Если отключение не подходит, оставьте стили плагина и переопределите нужные элементы через #gform_wrapper_N. После изменения пройдите форму клавишей Tab и отправьте пустое обязательное поле.
Ошибки при стилизации полей формы
Проверьте форму мышью, клавишей Tab и пробелом. Отдельные типы input нельзя оформлять одним широким сбросом.
| Ошибка | Что ломается | Как исправить |
|---|---|---|
outline: none без замены | Пропадает видимый фокус | Задайте контрастный outline через :focus-visible |
display: none у чекбокса | Элемент пропадает из клавиатурного управления | Оставьте input доступным и примените accent-color или appearance: none |
| Ширина у любого input | Чекбокс, radio и range получают размеры текста | Перечислите текстовые типы отдельно |
| Только красная рамка | Причина ошибки остается непонятной | Добавьте пояснение и свяжите его через aria-describedby |
| Разные шрифты формы и страницы | Размеры текста расходятся | Назначьте font: inherit полям и кнопкам |
| Устаревшие префиксы | CSS становится длиннее без пользы | Оставьте префиксы у специальных псевдоэлементов range |
Постоянный :invalid | Пустая форма выглядит ошибочной до ввода | Используйте :user-invalid или серверное состояние |
Для большинства форм хватит локального сброса, нативных переключателей и акцентного цвета. Полную замену оставьте дизайну с особыми индикаторами.
Совет от нашей редакции: сначала настройте клавиатурный фокус и связь label с input, затем меняйте цвета, размеры и системный вид элементов.
Популярное за неделю
- Как создать сайт самому в 2026: 4 способа + пошаговая инструкция 34 мин чтения
- Лучшие конструкторы для создания сайтов — плюсы, минусы и сравнения 22 мин чтения
- Программа для открытия XML файлов: чем смотреть и править выгрузки 14 мин чтения
- Что такое веб страница и как она работает 6 мин чтения
- Бесплатные адаптивные шаблоны HTML5/CSS3 для сайтов 5 мин чтения
- 20 адаптивных шаблонов на HTML5 и CSS3 3 мин чтения
Комментарии