UX форм: datalist, autocomplete, подсказки
Хорошая форма — не та, что строго проверяет, а та, что не мешает заполнять. Соберём инструменты удобства.
UX формы — это то, насколько легко её заполнить: подсказки на месте, автодополнение, правильная клавиатура, понятная подпись. HTML даёт для этого готовые атрибуты, которые часто важнее красивого CSS.
Можно сделать форму идеально валидной и при этом мучительной. Пользователь ошибается там, где ему не помогли: набирает то, что можно было подсказать; видит крестик-плейсхолдер вместо подписи и забывает, что за поле. В этом уроке — атрибуты, которые снимают трение.
Зачем это знать на практике
- Скорость. Автодополнение и
datalistэкономят набор: один тап вместо десяти. - Меньше ошибок. Правильная клавиатура и подсказки уменьшают опечатки.
- Доступность. Настоящая подпись
labelнужна скринридеру и увеличивает область нажатия.
datalist: автодополнение со своими вариантами
Элемент <datalist> — это список подсказок к обычному текстовому полю. В отличие от <select>, пользователь может выбрать вариант или ввести своё.
<label>Город
<input type="text" name="city" list="cities">
</label>
<datalist id="cities">
<option value="Москва">
<option value="Санкт-Петербург">
<option value="Казань">
<option value="Новосибирск">
</datalist>
Связь — через атрибут list у поля и совпадающий id у <datalist>. По мере ввода браузер фильтрует варианты. Это лучший выбор, когда подсказки полезны, но список не исчерпывающий: страны, теги, типичные домены почты.
autocomplete: помощь браузера и менеджера паролей
Атрибут autocomplete сообщает браузеру смысл поля, чтобы он предложил сохранённые данные: имя, адрес, карту. Это не «вкл/выкл», а словарь токенов.
| Токен | Назначение |
name | Полное имя |
email | Адрес почты |
tel | Телефон |
street-address | Адрес |
current-password | Текущий пароль (вход) |
new-password | Новый пароль (регистрация/смена) |
one-time-code | Код из СМС |
<input name="email" type="email" autocomplete="email">
<input name="pwd" type="password" autocomplete="current-password">
<input name="otp" inputmode="numeric" autocomplete="one-time-code">
Разделять current-password и new-password важно: по первому менеджер паролей подставит сохранённый пароль, по второму — предложит сгенерировать новый и не будет автозаполнять старым. Токен one-time-code на мобильных позволяет вставить код из СМС одним тапом.
placeholder не заменяет label
Самая частая ошибка удобства — подпись внутри поля как placeholder вместо настоящего <label>.
<!-- плохо: подпись исчезает, как только начинают вводить -->
<input type="text" placeholder="Имя">
<!-- хорошо: подпись остаётся всегда -->
<label for="name">Имя</label>
<input id="name" type="text" placeholder="например, Анна">
Почему placeholder — плохая подпись: он исчезает при вводе (пользователь забывает, что это за поле), его бледный серый цвет плохо читается, и скринридеры не всегда озвучивают его как подпись. Правильно: label — для названия поля, placeholder — для примера формата («например, +7 900...»). И клик по label ставит фокус в поле — больше площадь нажатия на телефоне.
inputmode: клавиатура без смены типа
Иногда нужен текст по смыслу, но цифровая клавиатура по факту — например, для номера карты или ПИН-кода (там нельзя type="number" из-за ведущих нулей и стрелок). Тогда тип оставляют текстовым, а клавиатуру задают через inputmode:
<label>Номер карты
<input type="text" inputmode="numeric" autocomplete="cc-number">
</label>
<label>Сумма
<input type="text" inputmode="decimal">
</label>
Полезные значения: numeric (только цифры), decimal (цифры с точкой), tel (звонилка), email, url, search. inputmode влияет только на вид клавиатуры и ничего не валидирует — это чистый UX-атрибут.
accept: фильтр файлов
Для type="file" атрибут accept подсказывает, какие файлы предлагать в диалоге выбора:
<input type="file" name="photo" accept="image/*">
<input type="file" name="doc" accept=".pdf,.doc,.docx">
<input type="file" name="gallery" accept="image/*" multiple>
Можно перечислить MIME-типы (image/*, application/pdf) или расширения (.pdf). Атрибут multiple разрешает выбрать несколько файлов сразу. Важно: accept только фильтрует подсказку в диалоге, но не гарантирует тип — проверку формата и размера всё равно делает сервер.
Многошаговые формы
Длинную форму (регистрация, оформление заказа) разбивают на шаги, чтобы не пугать «простынёй» полей. Базовый приём — группировать поля в <fieldset> с <legend> и показывать по одной группе:
<fieldset>
<legend>Шаг 1: контакты</legend>
<label>Имя <input name="name" required></label>
<label>Почта <input name="email" type="email" required></label>
</fieldset>
Принципы хорошего мастера: показывайте прогресс («Шаг 2 из 3»), не теряйте введённое при переходах «назад», валидируйте шаг перед переходом «вперёд». Сама пошаговость управляется скриптом, но семантика групп — это fieldset/legend, и она важна для доступности.
Как это работает под капотом
Атрибуты UX — это подсказки браузеру и ОС, а не жёсткие команды. autocomplete и list подключают встроенные механизмы автозаполнения; inputmode и связанный с типом режим запрашивают у мобильной ОС определённую раскладку; accept передаётся системному диалогу файлов. Браузер вправе подсказку проигнорировать (например, если у пользователя нет сохранённых адресов), и форма всё равно работает. Поэтому ни один из этих атрибутов нельзя считать гарантией — только улучшением.
Частые ошибки
- placeholder вместо label. Подпись исчезает при вводе и недоступна. Всегда давайте настоящий
<label>. - autocomplete=\"off\" на всё подряд. Мешает менеджерам паролей и автозаполнению адреса — пользователю труднее. Отключайте точечно и осознанно.
- Один autocomplete для входа и регистрации. Без разделения
current-password/new-passwordменеджер путается и подставляет не то. - type=\"number\" для карт и ПИН. Теряются ведущие нули, появляются ненужные стрелки. Берите
type=\"text\"+inputmode=\"numeric\". - Полагаться на accept как на проверку. Он лишь фильтрует диалог; тип и размер обязан проверить сервер.
Итоги
<datalist>+listдают автодополнение со своими вариантами, оставляя свободный ввод.autocomplete— словарь токенов (email,tel,current-password,new-password,one-time-code); разделяйте текущий и новый пароль.placeholder— пример формата, а не подпись; настоящую подпись даёт<label>(она же увеличивает зону нажатия).inputmodeменяет только клавиатуру (для карт/ПИН —type="text"+inputmode="numeric");acceptфильтрует файлы в диалоге.- Длинные формы дробят на шаги с
fieldset/legend; все UX-атрибуты — подсказки, а не гарантии.