</> Praktum

Главная / HTML / Формы HTML

Урок 5 · HTML

Формы: как получить данные от пользователя

Редакция PraktumОбновлено 16 минут на урок с практикойУровень: новичок

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

method="get"

Данные в адресе: ?q=flex. Для поиска и фильтров, результат можно сохранить ссылкой.

method="post"

Данные в теле запроса. Для заявок, регистрации, паролей и всего, что меняет данные на сервере.

Частые ошибки

  • Поле без 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 в браузере?

Для удобства — да, для безопасности — нет. Встроенную проверку легко обойти, поэтому сервер проверяет данные повторно.

Источники

Практикум по теме