Формы — поля ввода и валидация
Форма — это любое место где пользователь что-то вводит: имя, email, пароль, комментарий, число. ИИ генерирует формы постоянно — нужно понимать атрибуты, типы полей и встроенную валидацию.
Структура формы
<form> — обёртка. Внутри — <input>, <textarea>, <select>, <button>. По сабмиту (Enter в поле или клик по кнопке без type) — форма пытается отправиться. action и method у <form> определяют куда (без них браузер шлёт на текущую страницу). В современном вебе чаще ловят onSubmit и шлют JS-ом через fetch.
type — суперсила input
type="text" — обычный. type="email" — браузер сам валидирует @ и точку. type="password" — скрытый ввод. type="number" — только цифры + кнопки -/+. type="date" — выбор даты. type="checkbox" — галочка. type="radio" — выбор одного из. type="file" — загрузка файла. type="submit" — кнопка отправки. Использование правильного type = бесплатная мобильная клавиатура (на телефоне для type="email" появятся @ и .com).
label — связь с полем
<label for="email">Почта</label> + <input id="email" /> — клик на label фокусирует input. Альтернатива: обернуть input лейблом — <label>Почта <input /></label>. Для скринридера это критично — без связи он не знает что значит поле. Без label форма для слепого = поля «текст 1», «текст 2».
Встроенная валидация
required — поле обязательное. minlength / maxlength — границы длины. min / max — границы числа. pattern="регекс" — кастомное правило. Если форма не валидна, браузер сам не даст отправить и подсветит проблему. ИИ часто пишет ручную JS-валидацию там, где хватит required + type="email" — это перегиб.
<form action="/api/register" method="POST">
<!-- Имя — простой текст -->
<label for="name">Имя</label>
<input
type="text"
id="name"
name="name"
required
minlength="2"
placeholder="Алексей"
/>
<!-- Email — валидация формата автоматически -->
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
required
placeholder="you@example.com"
/>
<!-- Пароль — скрытый, минимум 8 -->
<label for="pass">Пароль</label>
<input
type="password"
id="pass"
name="password"
required
minlength="8"
/>
<!-- Возраст — число с границами -->
<label for="age">Возраст</label>
<input
type="number"
id="age"
name="age"
min="18"
max="120"
/>
<!-- Регион — выбор из вариантов -->
<label for="region">Регион</label>
<select id="region" name="region">
<option value="">— выберите —</option>
<option value="kyiv">Киев</option>
<option value="lviv">Львов</option>
<option value="other">Другой</option>
</select>
<!-- Согласие — чекбокс -->
<label>
<input type="checkbox" name="agree" required />
Соглашаюсь с условиями
</label>
<!-- Длинный текст -->
<label for="bio">О себе</label>
<textarea id="bio" name="bio" rows="4" maxlength="500"></textarea>
<button type="submit">Зарегистрироваться</button>
</form>
<!-- В JS обычно перехватывают сабмит -->
<script>
document.querySelector('form').addEventListener('submit', async (e) => {
e.preventDefault(); // не дать форме отправиться по-старому
const data = new FormData(e.target);
const r = await fetch('/api/register', { method: 'POST', body: data });
// ... обработать ответ
});
</script>Реальная форма регистрации со всем нужным