Урок 5 · HTML
Формы: как получить данные от пользователя
HTML-форма — это тег <form> с полями внутри: в них посетитель вводит имя, почту, вопрос или выбирает вариант. Каждому полю нужны подпись <label> и имя name, а кнопка type="submit" отправляет данные по адресу из атрибута action.
- Поля объединяет
form, отправляет —button type="submit". - У каждого поля видимая подпись
label, связанная черезforиid. - Без
nameзначение поля не отправится. method="get"— для поиска,post— для заявок и регистрации.- Тип поля (
email,tel) включает нужную клавиатуру и проверку.
Зачем этот урок сейчас
Почти каждый сайт что-то спрашивает: заявка, подписка, поиск, отзыв. После текста, ссылок и картинок формы — следующий шаг. Сделанная по правилам форма работает без строки JavaScript, понятна скринридеру и удобна на телефоне.
Минимальная форма
<form action="/subscribe" method="post">
<label for="email">Почта</label>
<input id="email" name="email" type="email" required>
<button type="submit">Подписаться</button>
</form>Подпись связана с полем: клик по слову «Почта» ставит курсор в поле, а скринридер называет поле этой подписью. type="email" покажет на телефоне клавиатуру с @, required не даст отправить пустое поле. По нажатию кнопки браузер отправит email=… на адрес /subscribe.
Из чего состоит форма
| Элемент | Зачем |
|---|---|
form | объединяет поля, знает адрес и способ отправки |
label | видимая подпись поля |
input | однострочное поле, галочка, переключатель, файл |
textarea | многострочный текст |
select + option | выпадающий список |
fieldset + legend | группа связанных полей с общим заголовком |
button | кнопка отправки или действия |
Почему label обязателен
<!-- связь через for и id -->
<label for="name">Как к вам обращаться</label>
<input id="name" name="name" autocomplete="name">
<!-- или поле внутри подписи -->
<label>
<input type="checkbox" name="agree" required>
Согласен с правилами
</label>Подпись нужна всем: зрячий видит, что вводить, скринридер читает название поля, а маленькая галочка становится кликабельной вместе с текстом. placeholder подпись не заменяет — серый текст исчезает, как только человек начинает печатать, и он забывает, что за поле перед ним.
name, id и value
Посетитель читает текст в label, а сервер получает пары name=значение. Если у поля нет name, оно не попадёт в отправку, даже если заполнено. id нужен, чтобы связать подпись с полем внутри страницы. Имя и id могут совпадать, но это разные атрибуты для разных задач.
У галочек и переключателей важен value: именно оно уйдёт на сервер. Галочка без value отправит слово on, а неотмеченная не отправит ничего.
action и method: куда и как отправлять
action — адрес, который примет данные: обработчик на сервере или сервис форм. Если action не указан, форма отправится на адрес текущей страницы.
<!-- поиск: ответы в адресной строке, ссылку можно скопировать -->
<form action="/search" method="get">
<label for="q">Поиск по урокам</label>
<input id="q" name="q" type="search">
<button>Найти</button>
</form>При get браузер откроет /search?q=flexbox — результат поиска можно сохранить в закладки. При post данные идут в теле запроса и не видны в адресе: так отправляют заявки, регистрацию, всё, что меняет данные или содержит личную информацию. Метод по умолчанию — get.
Типы полей
<input type="email" name="email" autocomplete="email">
<input type="tel" name="phone" autocomplete="tel">
<input type="password" name="password" minlength="8">
<input type="number" name="count" min="1" max="10">
<input type="date" name="date">
<textarea name="message" rows="5"></textarea>Правильный тип — бесплатная помощь: телефон покажет цифровую клавиатуру для tel, браузер проверит формат почты и предложит сохранённые данные через autocomplete. Все типы с примерами — в уроке input в HTML.
Группы полей: fieldset и legend
<fieldset>
<legend>Удобное время занятий</legend>
<label><input type="radio" name="time" value="evening"> По вечерам</label>
<label><input type="radio" name="time" value="weekend"> По выходным</label>
</fieldset>Переключатели одной группы получают общий name — тогда можно выбрать только один вариант. legend — вопрос, к которому относятся варианты: скринридер прочитает его вместе с каждым из них, и человек не услышит голое «По вечерам».
Встроенная проверка
| Атрибут | Что проверяет |
|---|---|
required | поле не пустое |
minlength, maxlength | длина текста |
min, max, step | диапазон чисел и дат |
pattern | соответствие регулярному выражению |
type="email", url | формат адреса |
Браузер не отправит форму и покажет подсказку у первого неверного поля. Но такую проверку легко обойти, поэтому сервер обязан проверять данные снова. Обязательные поля отмечай и атрибутом, и текстом: звёздочка без пояснения понятна не всем.
Кнопки в форме
<button type="submit">Отправить заявку</button>
<button type="button" class="show-password">Показать пароль</button>
<button type="reset">Очистить</button>Кнопка внутри формы по умолчанию имеет type="submit". Поэтому вспомогательную кнопку вроде «Показать пароль» обязательно помечай type="button", иначе клик отправит форму. Кнопку «Очистить» лучше не ставить: её путают с отправкой и теряют всё введённое.
get или post
Данные в адресе: ?q=flex. Для поиска и фильтров, результат можно сохранить ссылкой.
Данные в теле запроса. Для заявок, регистрации, паролей и всего, что меняет данные на сервере.
Частые ошибки
- Поле без
label— с подписью только в placeholder. - Нет
name, и заполненное поле не уходит на сервер. - Вспомогательная кнопка без
type="button"случайно отправляет форму. - Пароль или личные данные отправляются методом get и остаются в адресе и истории.
- Ошибку показывают только красной рамкой, без текста, что исправить.
Доступность
Форма доступна, когда у каждого поля есть видимая подпись, группы переключателей объединены в fieldset с legend, а ошибки выводятся текстом рядом с полем и связаны с ним через aria-describedby. Не выключай подсветку фокуса — по форме часто идут клавишей Tab. Не удаляй введённое после ошибки: заполнять всё заново тяжело каждому.
Поддержка браузерами
Теги форм и атрибуты required, minlength, pattern работают во всех актуальных браузерах. Типы date и time выглядят по-разному в разных браузерах и системах — это нормально, значение отправляется в едином формате ГГГГ-ММ-ДД.
Практика
Собери форму обратной связи: имя, почта, тема из выпадающего списка, сообщение и согласие с правилами. Имя, почта и согласие обязательны. Подписи свяжи с полями, кнопку отправки сделай явной, данные отправляй методом post на /feedback.
Показать решение
<form action="/feedback" method="post">
<label for="fb-name">Имя</label>
<input id="fb-name" name="name" autocomplete="name" required>
<label for="fb-email">Почта</label>
<input id="fb-email" name="email" type="email" autocomplete="email" required>
<label for="fb-topic">Тема</label>
<select id="fb-topic" name="topic">
<option value="question">Вопрос по уроку</option>
<option value="bug">Нашёл ошибку</option>
</select>
<label for="fb-message">Сообщение</label>
<textarea id="fb-message" name="message" rows="5"></textarea>
<label><input type="checkbox" name="agree" value="yes" required> Согласен с правилами</label>
<button type="submit">Отправить</button>
</form>Частые вопросы
Почему данные из поля не отправляются?
У поля нет атрибута name. Сервер получает пары «имя — значение», и поле без имени в отправку не попадает.
Можно ли обойтись без label, если есть placeholder?
Нет. placeholder исчезает при вводе, и его плохо читают скринридеры. Подпись должна быть видимой и связанной с полем.
Чем отличаются get и post?
get добавляет данные в адрес страницы и подходит для поиска. post отправляет их в теле запроса — для заявок, регистрации и личных данных.
Почему кнопка в форме отправляет её, хотя я не просил?
Кнопка внутри формы по умолчанию имеет type="submit". Для обычного действия укажи type="button".
Достаточно ли проверки required в браузере?
Для удобства — да, для безопасности — нет. Встроенную проверку легко обойти, поэтому сервер проверяет данные повторно.
Источники
Практикум по теме
- Подпись поля, которую читает и человек, и браузер — Placeholder внутри поля исчезает, когда начинают печатать. Подпись снаружи остаётся.