Дизайн форм UX: как проектировать поля ввода, лейблы и плейсхолдеры, чтобы пользователь не бросил заполнение

Дизайн форм UX: как проектировать поля ввода, лейблы и плейсхолдеры, чтобы пользователь не бросил заполнение

Коротко:

  • Лейбл внутри поля - это плейсхолдер, который исчезает при вводе. Пользователь теряет контекст и делает ошибки. Выносите подписи наружу.
  • Плейсхолдер - подсказка о формате, а не дублирование лейбла. Один из них лишний, если они говорят одно и то же.
  • Порядок вопросов влияет на конверсию сильнее, чем визуальное оформление. Начинайте с простого.
  • Тип поля input определяет клавиатуру на мобильном. Неправильный тип - лишнее трение при каждом вводе.
  • Когнитивная нагрузка от длинной анкеты снижается группировкой и прогрессом, а не сокращением полей ради сокращения.
  • В Figma компоненты полей ввода стоит собирать сразу с вариантами состояний: default, focus, filled, error, disabled.

Пользователь открывает форму регистрации, смотрит на неё три секунды и закрывает вкладку. Не потому что не хочет зарегистрироваться - а потому что форма с первого взгляда кажется сложной, непонятной или просто некомфортной. Это не редкость: по данным исследований Baymard Institute, около 81% пользователей бросали оформление заказа хотя бы раз, и значительная часть причин связана с самой структурой полей.

Эта статья не про валидацию и сообщения об ошибках - для этого есть отдельный материал. Здесь разбираем то, что происходит раньше: как устроена анатомия поля ввода, где лейблы работают, а где мешают, зачем плейсхолдер часто становится ловушкой и какой тип input выбрать под конкретный сценарий. Всё это напрямую влияет на то, дойдёт ли человек до кнопки «Отправить».

Анатомия поля ввода: что из чего состоит

Каждое поле в форме - это система из нескольких элементов. Путаница в их назначении приводит к типичным проблемам, которые трудно диагностировать на глаз.

ЭлементНазначениеГде размещать
Лейбл (label)Постоянная подпись - что нужно ввестиНад полем или слева от него
Плейсхолдер (placeholder)Временная подсказка о формате вводаВнутри поля, исчезает при фокусе или вводе
Хелпер-текст (helper text)Дополнительное пояснение или требованиеПод полем, всегда видим
Префикс / суффиксЕдиница измерения, символ валюты, иконкаВнутри поля, по краям
Счётчик символовОграничение длиныПод полем, справа

Проблема начинается, когда лейбл и плейсхолдер смешиваются в один элемент. Паттерн «floating label» - когда подпись живёт внутри поля и всплывает вверх при фокусе - кажется элегантным, но создаёт несколько практических проблем. О них подробнее в следующем разделе.

Лейбл внутри поля: когда это ошибка

Floating label стал модным примерно после того, как Google Material Design использовал его в своих компонентах. Многие команды внедрили паттерн, не разобравшись в ограничениях.

Вот конкретные ситуации, где он ломает сценарий:

  • Пользователь заполнил поле и переключился на другое. Лейбл всплыл вверх и уменьшился. При возврате к полю подпись визуально конкурирует с введённым значением - особенно на маленьком экране.
  • Автозаполнение браузера. Когда браузер подставляет значение, floating label часто остаётся в базовом положении и накладывается на текст. Поле выглядит сломанным.
  • Пользователь с нарушениями зрения или при низком контрасте. Мелкий всплывший лейбл теряет читаемость. По WCAG 2.1 контраст для текстовых меток должен быть минимум 4.5:1, а уменьшенный floating label часто этого не обеспечивает.
  • Формы в стрессовом сценарии. Регистрация на кассе, бронирование в последний момент, заполнение данных карты - в таких ситуациях пользователь сканирует форму быстро. Лейблы над полями считываются за долю секунды; всплывающие подписи требуют чуть больше внимания.

Практическое правило: если сомневаетесь, ставьте лейбл над полем. Это работает в 95% случаев и не создаёт исключений. Floating label оправдан только в очень компактных интерфейсах с одним-двумя полями, где экономия пространства критична.

Плейсхолдеры: что они должны делать и чего не должны

Плейсхолдер существует для одного: показать формат ввода. Не название поля, не обязательность, не мотивацию заполнить - только формат.

Правильно: поле «Телефон», плейсхолдер - «+7 (900) 000-00-00»
Неправильно: поле без лейбла, плейсхолдер - «Введите ваш номер телефона»

Когда плейсхолдер дублирует лейбл, один из них лишний. Чаще убирают лейбл и оставляют только плейсхолдер - и получают форму, которая кажется компактной, но ломается при первом же вводе: пользователь начал печатать и уже не помнит, что именно он заполняет.

Ещё одна распространённая ошибка - использовать плейсхолдер для обязательных требований: «минимум 8 символов», «только латиница», «без пробелов». Это информация, которая нужна пользователю в процессе ввода и после него. Когда она исчезает при первом нажатии клавиши, человек либо не успевает её прочитать, либо вынужден стирать введённое, чтобы посмотреть снова. Такие требования - в хелпер-текст под полем.

Порядок полей: почему «логика формы» и «логика пользователя» расходятся

Типичная ошибка при проектировании длинных анкет - выстраивать поля в том порядке, в котором данные нужны системе. База данных ждёт: имя, фамилия, email, телефон, дата рождения, город. Форма повторяет этот порядок. Пользователь воспринимает её как бюрократический опрос.

Несколько принципов, которые реально влияют на заполнение:

  1. Начинайте с простого и нейтрального. Имя и email вводятся без раздумий. Паспортные данные, ИНН, банковские реквизиты - в конец. К тому моменту пользователь уже вложил усилия и с меньшей вероятностью бросит.
  2. Группируйте по смыслу, не по типу данных. «Контактные данные» как блок воспринимается легче, чем вперемешку имя, телефон, адрес и email.
  3. Не задавайте вопросы, ответ на которые уже известен. Если пользователь выбрал страну доставки на предыдущем шаге, не просите её снова в форме оплаты.
  4. Условные поля показывайте только когда они нужны. Поле «Название компании» появляется, только если выбран тип «Юридическое лицо». Это снижает визуальный объём и убирает нерелевантные вопросы.

Какой тип поля выбрать: input, select, radio, textarea и другие

Выбор типа элемента - не эстетическое решение. Он определяет скорость ввода, вероятность ошибки и поведение на мобильном устройстве.

СценарийТип элементаПочему
2-4 варианта, нужно видеть все сразуRadio buttonНе требует раскрытия, все варианты на виду
5+ вариантов или динамический списокSelect / ComboboxЭкономит место, поддерживает поиск
Независимые опции, можно выбрать несколькоCheckboxКаждая опция независима
Длинный свободный текстTextareaВидно объём, нет ощущения обрезки
Одна строка текстаinput type= 

Мобильный ввод: как тип поля меняет клавиатуру

На десктопе тип input почти не влияет на внешний вид. На мобильном он напрямую определяет, какая клавиатура появится у пользователя. Это одна из самых частых точек невидимого трения: пользователь хочет ввести номер карты, а у него открывается полная буквенная клавиатура.

Несколько конкретных случаев, где правильный тип поля экономит время:

  • Телефон: используйте type="tel". На iOS и Android откроется цифровая клавиатура с символами звёздочки и решётки. Без этого атрибута пользователь получает стандартную буквенную раскладку.
  • Email: type="email" даёт клавиатуру с символами @ и точки на виду. Плюс браузер автоматически предложит адреса из истории.
  • Числовые значения: type="number" подходит для количества или возраста. Для кода подтверждения лучше type="tel", потому что number-клавиатура на некоторых устройствах показывает стрелки вверх-вниз, которые здесь бесполезны.
  • Поиск: type="search" меняет кнопку Enter на значок лупы или слово «Найти» в зависимости от платформы.
  • Дата: нативный type="date" открывает системный датапикер. Это быстрее, чем три отдельных поля для дня, месяца и года, но выглядит по-разному на iOS и Android. Если визуальная консистентность важна, используйте кастомный компонент и явно указывайте ожидаемый формат в хелпер-тексте.

Правило простое: прежде чем финализировать форму, проверьте каждое поле с телефона. Если появляется неудобная клавиатура, это баг дизайна, а не разработки.

Ширина поля как подсказка

Ширина поля ввода сигнализирует пользователю об ожидаемом объёме данных. Это называется affordance через размер. Когда все поля одинаковой ширины - имя, индекс, комментарий, - форма выглядит нейтрально, но теряет один из бесплатных способов направлять внимание.

Несколько рабочих соответствий:

  • Поле для имени и фамилии - средняя ширина, примерно половина доступной строки.
  • Почтовый индекс, код подтверждения, CVV - короткое поле. Пользователь сразу понимает, что значений немного.
  • Адрес, название компании - полная ширина.
  • Комментарий или описание - textarea с явной высотой, чтобы было понятно: здесь можно писать много.

На мобильном ширина почти всегда равна ширине экрана, поэтому этот приём работает преимущественно на десктопе. Но даже на мобильном высота textarea и наличие счётчика символов выполняют ту же функцию - задают ожидание.

Быстрый чеклист перед финальным ревью формы:

  • У каждого поля есть видимый лейбл вне поля
  • Плейсхолдер показывает формат, а не дублирует подпись
  • Требования к формату вынесены в хелпер-текст под полем
  • Поля расположены от простого к сложному
  • Условные поля скрыты до момента, когда они нужны
  • Каждый input проверен с мобильного устройства - нужная клавиатура появляется
  • Ширина поля соответствует ожидаемому объёму данных
  • Все состояния собраны в компоненте: default, focus, filled, error, disabled

Группировка и прогресс: как снизить ощущение объёма

Длинная форма из двадцати полей на одном экране психологически тяжелее, чем четыре шага по пять полей - даже если суммарное количество вопросов одинаково. Это эффект чанкинга: люди воспринимают сгруппированную информацию как менее объёмную.

Несколько подходов, которые реально работают:

Визуальная группировка без пагинации. Если форма умещается на одном экране, но содержит разнородные блоки, разделите их подзаголовками и небольшим отступом. Блок «Личные данные», затем «Адрес доставки», затем «Способ оплаты» - пользователь понимает структуру и видит, что остаётся пройти.

Многошаговая форма с индикатором прогресса. Работает для длинных анкет или сценариев с высокой ставкой: оформление заказа, регистрация в сервисе, заявка на услугу. Индикатор должен показывать не просто номер шага, но и его название - «Шаг 2 из 4: Адрес доставки» понятнее, чем просто точки.

Ленивое раскрытие. Начните с одного-двух ключевых полей, а остальные показывайте по мере заполнения. Этот подход снижает первый визуальный барьер, но требует аккуратной реализации: пользователь должен понимать, что форма продолжится, а не думать, что она уже завершена.

Сценарий формыРекомендуемая структураПочему
До 6 полейОдин экран без разделенияГруппировка добавит лишний визуальный вес
7-15 полей с логическими блокамиОдин экран с подзаголовками-разделителямиСтруктура видна, прокрутка не пугает
15+ полей или разные типы данныхМногошаговая форма с прогрессомСнижает когнитивную нагрузку, позволяет сохранять шаги
Формы с условными веткамиДинамическое раскрытие + индикаторПоказывает только релевантные вопросы

Важный момент с многошаговыми формами: всегда предусматривайте возможность вернуться на предыдущий шаг без потери данных. Пользователь, который потерял введённое при нажатии «Назад», скорее всего уйдёт. Это не только проблема разработки - дизайнер должен явно задать это поведение в хендофе, а не оставлять на усмотрение разработчика.

Автозаполнение: как помочь браузеру и сэкономить время пользователя

Одна из самых недооценённых возможностей при проектировании полей ввода - корректное использование атрибута autocomplete. Когда он задан правильно, браузер подставляет имя, адрес, данные карты или email за пользователя. Это экономит минуты, особенно на мобильном устройстве.

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

Несколько конкретных значений, которые стоит указывать явно:

  • autocomplete="name" или given-name / family-name" для полей имени
  • autocomplete="email" для электронной почты
  • autocomplete="tel" для телефона
  • autocomplete="street-address", postal-code", address-level2" для адреса
  • autocomplete="new-password" для поля создания пароля - отдельно от current-password", чтобы браузер не подставлял старый пароль
  • autocomplete="one-time-code" для кодов подтверждения: на iOS это позволяет автоматически вставить код из SMS прямо в поле

Это решение почти бесплатное с точки зрения дизайна - его просто нужно передать в хендоф как явное требование к разработке. Но на практике именно здесь чаще всего появляется пробел между макетом и реализацией.

Обязательные и необязательные поля: как обозначать без путаницы

Большинство форм маркирует обязательные поля красной звёздочкой (*). Это устоявший паттерн, но он работает хуже, чем кажется, по нескольким причинам.

Во-первых, пользователи часто не замечают звёздочку до первой попытки отправить форму. Во-вторых, если почти все поля обязательны, звёздочки превращаются в визуальный шум, который никто не читает. В-третьих, слабовидящие пользователи и скринридеры не всегда корректно обрабатывают звёздочку как смысловой маркер без дополнительного aria-атрибута.

Более практичный подход: маркируйте то, что является исключением. Если форма почти полностью обязательная, отмечайте только необязательные поля пометкой «необязательно» рядом с лейблом. Это текст, а не символ - его сложнее пропустить и легче понять.

Практическое правило выбора маркировки:

  • Если обязательных полей больше половины - помечайте только необязательные словом «необязательно»
  • Если необязательных полей больше половины - помечайте обязательные звёздочкой с расшифровкой в начале формы
  • Если все поля обязательны - не помечайте ничего, напишите об этом один раз над формой
  • Всегда добавляйте aria-required="true" для обязательных полей независимо от визуальной маркировки

Ещё один момент, который часто упускают: если поле необязательное, стоит сразу объяснить, зачем оно вообще здесь. «Телефон (необязательно, нужен для уточнения заказа)» конвертирует лучше, чем просто «Телефон (необязательно)» - пользователь понимает ценность и принимает осознанное решение.

Чеклист финального ревью: что проверить перед передачей в разработку

Дизайн поля ввода редко ломается в одном месте. Чаще это несколько мелких упущений, которые в сумме дают форму, которую неприятно заполнять. Ниже - структурированный список для проверки перед хендофом.

Область проверкиЧто проверитьЧастая ошибка
ЛейблыКаждое поле имеет видимую подпись вне поляЛейбл только внутри как плейсхолдер
ПлейсхолдерыПоказывают формат, не дублируют лейблПлейсхолдер заменяет лейбл
Хелпер-текстТребования к формату написаны под полем, всегда видимыТребования только в плейсхолдере
Маркировка обязательностиЛогика маркировки соответствует составу формыЗвёздочки везде без расшифровки
Типы полейКаждый input проверен с мобильного, нужная клавиатура появляетсяЧисловые поля без type="tel" или type="number"
АвтозаполнениеАтрибут autocomplete указан для стандартных данныхАтрибут отсутствует или отключён везде
СостоянияКомпонент содержит default, focus, filled, error, disabledТолько дефолтное состояние в макете
Условные поляСкрыты до нужного момента, появляются по логикеВсе поля показаны сразу
ДоступностьКонтраст лейблов минимум 4.5:1, aria-атрибуты заданыМелкий серый текст хелпера

Этот список удобно добавить в шаблон хендофа или в комментарии к компоненту в Figma. Тогда проверка становится частью процесса, а не отдельным этапом перед релизом.

Связь лейбла и поля: доступность как базовое требование

Визуально красивая форма может быть полностью сломана для пользователей скринридеров и клавиатурной навигации, если лейблы не привязаны к полям программно.

Самая частая проблема: дизайнер размещает текст рядом с полем, но без явной связи через атрибут for в HTML. На макете всё выглядит правильно, разработчик реализует «как нарисовано», а скринридер читает поле без подписи вообще.

Несколько правил, которые стоит фиксировать в хендофе:

  • Каждый label должен быть связан с input через атрибуты for и id. Это не только доступность: при правильной связке клик по тексту лейбла автоматически переводит фокус в поле, что увеличивает кликабельную область.
  • Если лейбл визуально скрыт по дизайн-решению, он всё равно должен присутствовать в разметке или через aria-label. Скрытый лейбл лучше, чем отсутствующий.
  • Иконки внутри поля без подписи нужно сопровождать aria-label или скрытым текстом. Иконка лупы без подписи понятна зрячему пользователю, но не тому, кто использует скринридер.
  • Хелпер-текст под полем привязывается через aria-describedby. Без этого пользователь со скринридером прочитает подсказку только если специально до неё доберётся, а не при переходе на поле.

Это не дополнительный список требований к доступности - это базовая корректность реализации. Дизайнер не пишет HTML, но именно он задаёт структуру в хендофе. Если не обозначить эти связи явно, разработчик часто реализует «по внешнему виду».

Состояния поля в контексте длинного сценария

Статья про состояния UI-компонентов рассматривает hover, focus, error и disabled как отдельные случаи. Но в длинной анкете они взаимодействуют между собой, и это создаёт отдельный класс проблем.

Рассмотрим конкретный сценарий: пользователь заполняет форму из 12 полей, возвращается к уже заполненному полю и меняет значение. Какое состояние показывать? Filled? Focus + filled? А если в этом поле раньше была ошибка и пользователь её исправил - нужно ли убирать красную рамку сразу при вводе или только после потери фокуса?

Рекомендуемая логика смены состояний для полей с валидацией:

  • Ошибка появляется после потери фокуса (on blur), не в процессе ввода
  • Ошибка снимается сразу при начале исправления, не после потери фокуса
  • Состояние «filled» (заполнено, без ошибки) показывается после потери фокуса при корректном значении
  • Повторный фокус на заполненном поле возвращает состояние focus, но сохраняет значение
  • При отправке формы с ошибками фокус автоматически переходит на первое поле с ошибкой

Эту логику нужно описать явно в документации компонента или в комментариях к макету. Разработчик не угадает её из статичного экрана, а неправильная реализация создаёт раздражающие моменты: ошибка появляется слишком рано, или, наоборот, не пропадает после исправления.

Ещё один момент, который часто упускают в длинных формах: состояние «в процессе» для всей формы. Если пользователь начал заполнение и ушёл, а форма поддерживает сохранение черновика, нужно визуально показать, какие поля уже заполнены и можно ли продолжить с того места, где остановился. Это отдельный сценарий, который стоит прорабатывать вместе с менеджером продукта ещё на этапе структуры.

Сравнение подходов к проектированию поля: что выбрать под разный контекст

Не существует универсальной конфигурации поля ввода. То, что работает в форме регистрации, может быть избыточным в строке поиска, и наоборот. Ниже - сводная таблица, которая помогает выбрать подход под конкретный контекст.

КонтекстЛейблПлейсхолдерХелпер-текстОсобенности
Регистрация и авторизацияНад полем, всегда видимФормат при необходимостиТребования к паролюautocomplete обязателен
Форма оформления заказаНад полем, всегда видимПример форматаТолько при неочевидных требованияхМаксимальное автозаполнение
Поисковая строкаСкрытый aria-labelПодсказка о том, что искатьНе нуженtype=