Формы в HTML и CSS: первые шаги для владельца сайта
За полчаса вы соберёте рабочую форму обратной связи: разметка на HTML, проверка полей средствами браузера и аккуратное оформление на CSS. Без JavaScript и без фреймворков.

К концу этой инструкции у вас будет форма обратной связи, которая проверяет обязательные поля, подсвечивает ошибки красным и выглядит опрятно на телефоне и на десктопе. На это уйдёт 30–40 минут. JavaScript не понадобится: браузер умеет проверять поля сам, а внешний вид полностью задаётся на CSS.
Материал написан под актуальные версии Chrome, Firefox и Safari (2024 год). Всё, что здесь показано, работает в браузерах последних пяти лет — специальных полифилов не нужно.
Что нужно иметь до начала
- Любой текстовый редактор. Подойдёт даже «Блокнот», но удобнее VS Code или Notepad++ — они подсвечивают теги.
- Браузер для проверки — тот, что уже стоит.
- Один пустой файл с именем
form.html. Стили положим в него же, чтобы не жонглировать двумя файлами.
Отправку данных на сервер здесь не рассматриваем — это отдельная тема, требующая либо серверного скрипта, либо стороннего сервиса. Пока форма будет собирать и проверять данные, а по нажатию кнопки — обновлять страницу. Этого достаточно, чтобы понять, как устроена разметка.
Шаг 1. Каркас страницы
Создайте form.html и вставьте туда базовый каркас. Кодировку utf-8 ставим сразу, иначе кириллица превратится в кракозябры.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Обратная связь</title>
</head>
<body>
</body>
</html>Откройте файл двойным кликом. Проверка: в браузере открылась пустая белая страница, а во вкладке видно заголовок «Обратная связь». Если вкладка называется как-то иначе — вы открыли не тот файл.
Шаг 2. Сама форма
Всё, что относится к форме, оборачивается в тег <form>. Каждое поле состоит из двух частей: подписи <label> и самого поля ввода <input> или <textarea>. Вставьте этот блок внутрь <body>:
<form>
<h1>Напишите нам</h1>
<label for="name">Имя</label>
<input type="text" id="name" name="name" required>
<label for="email">Электронная почта</label>
<input type="email" id="email" name="email" required>
<label for="message">Сообщение</label>
<textarea id="message" name="message" rows="4" required></textarea>
<button type="submit">Отправить</button>
</form>Проверка: обновите страницу — появились три поля с подписями и кнопка «Отправить».
Зачем связка for и id
Атрибут for у подписи должен совпадать с id поля. Тогда клик по слову «Имя» ставит курсор в нужное поле — это удобно на телефоне и обязательно для программ чтения с экрана. Атрибут name — это ключ, под которым значение уйдёт на сервер; без него поле для отправки бесполезно.
Шаг 3. Проверка полей средствами браузера
Атрибут required вы уже поставили — он не даст отправить форму с пустым полем. Тип type="email" заставляет браузер проверять, что в поле есть символ @ и точка. Это встроенная валидация, JavaScript для неё не нужен.
Проверка: нажмите «Отправить», не заполнив поля. Браузер покажет всплывающую подсказку у первого пустого поля и не отправит форму. Введите в поле почты просто привет — браузер сообщит, что адрес неполный.
Половина «форм с проверкой» на самом деле проверяют данные скриптом там, где хватило бы одного слова required в разметке. Начинайте с возможностей браузера, а скрипт добавляйте, только когда их не хватает.Часто нужные атрибуты полей:
| Атрибут | Что делает |
|---|---|
required | поле нельзя оставить пустым |
type="email" | проверяет формат адреса |
type="tel" | на телефоне открывает цифровую клавиатуру |
minlength="10" | требует минимум 10 символов |
placeholder="..." | серая подсказка внутри поля |
Помните: placeholder — не замена label. Подсказка исчезает, как только человек начинает печатать, и он забывает, что за поле перед ним. Подпись оставляйте всегда.
Шаг 4. Оформление на CSS
Пока форма выглядит как набор строк без отступов. Добавьте блок стилей в <head>, сразу после <title>:
<style>
form {
max-width: 420px;
margin: 40px auto;
font-family: system-ui, sans-serif;
}
label {
display: block;
margin-top: 16px;
font-weight: 600;
}
input, textarea {
width: 100%;
padding: 10px;
margin-top: 6px;
border: 1px solid #ccc;
border-radius: 6px;
box-sizing: border-box;
font-size: 16px;
}
button {
margin-top: 20px;
padding: 12px 24px;
border: none;
border-radius: 6px;
background: #2563eb;
color: #fff;
font-size: 16px;
cursor: pointer;
}
</style>Проверка: обновите страницу. Форма стала уже, поля растянулись на всю её ширину, подписи встали над полями, кнопка синяя.
Почему box-sizing здесь важен
Свойство box-sizing: border-box включает внутренние отступы и рамку в ширину поля. Без него width: 100% плюс padding: 10px дают ширину чуть больше контейнера, и поле вылезает за край. Это самая частая причина «съехавшей» формы у новичков.
font-size: 16px у полей — не про красоту. Если шрифт меньше, Safari на iPhone автоматически увеличивает всю страницу при клике в поле. 16 пикселей это отключают.
Шаг 5. Подсветка ошибок
CSS умеет реагировать на состояние поля. Добавьте в блок <style> ещё пару правил:
input:focus, textarea:focus {
outline: none;
border-color: #2563eb;
}
input:required:invalid {
border-color: #dc2626;
}Псевдокласс :invalid срабатывает, когда содержимое поля не проходит проверку — например, почта без @. Проверка: введите в поле почты неверный адрес и уведите курсор — рамка станет красной.
Если не получилось
- Кириллица превратилась в «Ð¿Ñ€Ð¸Ð²ÐµÑ‚». Не хватает
<meta charset="utf-8">в<head>либо файл сохранён не в UTF-8. В VS Code кодировка видна в правом нижнем углу. - Клик по кнопке ничего не делает и не ругается. Проверьте, что у кнопки
type="submit", а неtype="button". - Поля вылезают за край формы. Не задан
box-sizing: border-boxуinputиtextarea. - Клик по подписи не ставит курсор в поле. Значение
forу<label>не совпадает сidполя — сверьте посимвольно. - Стили вообще не применились. Блок
<style>оказался внутри<body>или вы забыли закрыть</style>. Он должен быть в<head>.
Что делать дальше
Форма собрана и проверяет данные, но пока никуда их не отправляет. Следующий шаг — заставить её работать. Два реалистичных пути:
- Подключить готовый сервис приёма форм (Formspree, Getform и подобные): вы прописываете их адрес в атрибут
actionформы, письма приходят вам на почту — сервер писать не нужно. - Если у сайта есть бэкенд — отправлять данные на свой обработчик и там сохранять их или пересылать письмом.
Когда дойдёте до отправки, почитайте про атрибуты action и method у тега <form> в документации MDN — там же разобраны все типы полей и псевдоклассы валидации.
Оформление по ГОСТ: Поля, шрифты, нумерация, сноски, титульный лист
Спросить за 10 ₽Источники: MDN Web Docs — Формы: руководство, MDN Web Docs — Валидация форм на стороне клиента
Частые вопросы
А если у меня старый браузер — проверка полей сработает?
Почему форма не отправляет данные мне на почту?
Обязательно ли выносить стили в отдельный CSS-файл?
Чем input отличается от textarea?
Placeholder может заменить подпись label?
Красная рамка появляется сразу при загрузке пустой формы — это нормально?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.