Верстка форм
Конспект лекції: елементи форм, стилізація полів, валідація, label, outline, стани :focus та :hover
Навіщо потрібні форми?
Форми — спосіб отримати дані від користувача: ім'я, email, повідомлення, вибір опцій тощо.
- Текстові поля —
<input>(однорядкове),<textarea>(багаторядкове). - Чекбокси — вибір кількох варіантів зі списку.
- Радіокнопки — вибір одного варіанту зі списку.
- Випадаючі списки —
<select>. - Кнопки — відправлення, скидання, дія.
Тег <input> — однорядкове поле
<input> — самозакривний тег. Тип визначається атрибутом type:
| Тип | Призначення |
|---|---|
text (за замовчуванням) |
Звичайне текстове поле |
password |
Пароль (символи приховані) |
email |
Email (вбудована перевірка на @) |
search |
Пошук (має кнопку очищення ×) |
number |
Число (стрілки ↑↓, атрибути min, max, step) |
date |
Дата (календар браузера) |
time |
Час |
datetime-local |
Дата + час |
range |
Повзунок |
color |
Вибір кольору |
Атрибути input
| Атрибут | Призначення |
|---|---|
placeholder |
Підказка всередині поля (зникає при введенні) |
value |
Значення за замовчуванням (як ніби користувач вже ввів) |
name |
Ім'я поля для відправлення на сервер |
required |
Поле обов'язкове (форма не відправиться без нього) |
disabled |
Поле заблоковане (не можна редагувати) |
id |
Унікальний ідентифікатор (для зв'язку з <label>) |
autocomplete |
Підказка браузеру, що автозаповнювати ("name", "email", "tel"…)
|
autocomplete — автозаповнення браузером
Атрибут autocomplete підказує браузеру, яку збережену інформацію підставити в поле:
<input type="text" name="fullname" autocomplete="name">
<input type="email" name="email" autocomplete="email">
<input type="tel" name="phone" autocomplete="tel">
autocomplete покращує UX: браузер пропонує збережені дані в один клік.
Особливо важливо на мобільних пристроях.
placeholder — це приклад очікуваного значення (наприклад, «Іван
Петренко»).<label> або підказка — це назва поля (наприклад, «Ваше ім'я»).
Стилізація input
<input> можна стилізувати як будь-який блочний елемент:
.field {
width: 100%;
padding: 10px 15px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 16px;
box-sizing: border-box;
background-color: #fff;
color: #333;
}
box-sizing: border-box для полів форми — інакше
padding збільшить загальну ширину елемента.
accent-color — стилізація чекбоксів та радіокнопок
Раніше змінити колір чекбокса або радіокнопки було неможливо без хаків. Сучасна властивість accent-color
вирішує це одним рядком:
/* Усі інтерактивні елементи — в кольорах бренду */
input[type="checkbox"],
input[type="radio"],
input[type="range"] {
accent-color: #e53935;
}
accent-color підтримується усіма сучасними браузерами з 2022 року. Працює для
checkbox, radio, range та progress.
Тег <textarea> — багаторядкове поле
- На відміну від
<input>, має закривний тег:<textarea>...</textarea>. - Текст між тегами — значення за замовчуванням.
- Користувач може змінювати розмір (перетягування кутка).
Обмеження розміру
textarea.field {
min-width: 250px;
max-width: 100%;
min-height: 100px;
max-height: 300px;
font-family: inherit; /* без цього — моноширинний шрифт! */
}
<textarea> за замовчуванням має моноширинний шрифт (monospace). Задайте
font-family: inherit, щоб успадкувати шрифт від батька.
min-width і max-width, щоб заборонити горизонтальну
зміну розміру. Аналогічно для висоти.
Кнопки <button>
Три типи кнопок:
| Тип | Поведінка |
|---|---|
submit |
Відправляє форму (потрібен тег <form>) |
reset |
Скидає всі поля до значень за замовчуванням |
button |
Нічого не робить (для JavaScript-обробників) |
Стилізація кнопки
.button {
padding: 12px 24px;
border: none;
background-color: #e53935;
color: #fff;
font-size: 16px;
font-family: inherit;
cursor: pointer; /* лапка при наведенні */
border-radius: 4px;
}
border,
background, font-family і стилізуйте з нуля.
cursor: pointer — за замовчуванням на кнопках курсор-стрілка, а не
лапка.
Тег <label> — підпис поля
<label> — семантичний елемент, що зв'язує текст підпису з полем введення.
Два способи зв'язування
1. Обгортка — input всередині label:
<label>
<span class="hint">Ваше ім'я</span>
<input type="text" class="field">
</label>
2. Атрибут for + id — label окремо від input:
<label for="user-email">Email</label>
<input type="email" id="user-email" class="field">
<label> автоматично ставить фокус на пов'язаний input. Це зручно для
UX і важливо для доступності (скрінрідери).
Тег <form>
<form> об'єднує поля в єдину форму. Без нього кнопка submit не працюватиме.
<form action="/api/contact" method="POST">
<label>
<span class="hint">Ім'я</span>
<input type="text" name="username" required>
</label>
<button type="submit">Надіслати</button>
</form>
| Атрибут | Призначення |
|---|---|
action |
URL, куди відправляються дані |
method |
HTTP-метод: GET або POST |
<form> — не просто семантичний тег. Він має практичне значення: об'єднує
поля, додає подію submit, дозволяє кнопці type="submit" працювати.
Валідація полів
HTML має вбудовані валідатори — перевірки перед відправленням форми:
| Спосіб | Що перевіряє |
|---|---|
required |
Поле не порожнє |
type="email" |
Наявність символу @ |
min / max |
Діапазон числового значення |
minlength / maxlength |
Мінімальна / максимальна кількість символів |
pattern |
Перевірка за регулярним виразом |
required (чи не порожнє), потім type (формат), потім
pattern та інші обмеження.
Стани :focus та :hover
:focus — поле у фокусі
Коли користувач клікнув на поле або перейшов клавішею Tab:
.field:focus {
outline: 2px solid #1976d2;
outline-offset: 2px;
}
:focus-visible — фокус тільки з клавіатури
Проблема :focus: outline з'являється і при кліку мишею, що дратує дизайнерів. Рішення — :focus-visible:
/* Прибираємо outline при кліку мишею */
.field:focus {
outline: none;
}
/* Показуємо outline тільки при навігації клавіатурою */
.field:focus-visible {
outline: 2px solid #1976d2;
outline-offset: 2px;
}
:focus-visible підтримується усіма сучасними браузерами з 2022 року. Це
стандартний підхід: красиво для миші, доступно для клавіатури.
:hover — наведення мишею
.field:hover {
border-color: #666;
}
outline для клавіатурного фокусу — це критично для
доступності. Використовуйте :focus-visible, щоб outline з'являвся лише при навігації
клавіатурою, а не при кліку мишею.
Властивість outline
outline — обведення навколо елемента, яке не впливає на розміри та розкладку.
| Властивість | Що задає |
|---|---|
outline-width |
Товщина обведення |
outline-style |
solid, dotted, dashed, none |
outline-color |
Колір обведення |
outline-offset |
Відстань від межі елемента до обведення |
outline |
Скорочення: width style color |
outline не входить до блочної моделі — навіть із border-box він не
змінює розмір елемента. Це ключова відмінність від border.
Групування селекторів
Якщо кілька елементів мають однакові стилі, їх селектори можна перелічити через кому:
/* Замість дублювання: */
.field:focus,
.button:focus {
outline: 2px solid #1976d2;
outline-offset: 2px;
}
/* Однакові шрифти для заголовків: */
h1,
h2,
h3 {
font-family: "Segoe UI", sans-serif;
}
Структура форми: повний приклад
<form class="contact-form" action="/api/contact" method="POST">
<div class="form-row">
<label class="form-group">
<span class="form-hint">Ваше ім'я</span>
<input type="text" class="field"
name="username" placeholder="Іван Петренко" required>
</label>
</div>
<div class="form-row">
<label class="form-group">
<span class="form-hint">Email</span>
<input type="email" class="field"
name="email" placeholder="name@example.com" required>
</label>
</div>
<div class="form-row">
<label class="form-group">
<span class="form-hint">Повідомлення</span>
<textarea class="field"
name="message" placeholder="Ваше повідомлення..." required></textarea>
</label>
</div>
<div class="form-row">
<button type="submit" class="button">Надіслати</button>
</div>
</form>
/* CSS для відступів між рядками форми */
.form-row:nth-child(n+2) {
margin-top: 20px;
}
.form-hint {
display: block;
margin-bottom: 6px;
font-weight: 600;
}
Налагодження станів у DevTools
У DevTools (інспекторі браузера) є панель :hov, яка дозволяє емулювати псевдостани:
- Виділіть елемент у вкладці Elements.
- Натисніть кнопку :hov (у панелі Styles).
- Увімкніть
:focus,:hover,:activeтощо. - Стилі цього стану стануть видимими та редагованими.
:hover + :focus),
щоб побачити, який стиль перекриває інший.
Підсумок
| Тема | Ключове |
|---|---|
<input> |
Однорядкове поле; type визначає тип (text, email, number…) |
<textarea> |
Багаторядкове поле; font-family: inherit; обмежити розмір |
<button> |
submit (відправити), reset (скинути), button (JS) |
<label> |
Підпис поля; клік → фокус; зв'язок через обгортку або for+id |
<form> |
Об'єднує поля; action + method; подія submit |
placeholder |
Приклад значення (не замінює label!) |
required |
Обов'язкове поле (вбудована валідація) |
outline |
Обведення при фокусі; не впливає на розміри; не видаляйте! |
:focus / :hover |
Стани для інтерактивних елементів; відлагоджувати через :hov у DevTools |
cursor: pointer |
Лапка на кнопках (за замовчуванням — стрілка) |
:focus-visible |
Outline тільки при навігації клавіатурою (не при кліку мишею) |
accent-color |
Колір checkbox, radio, range — одним рядком CSS |
autocomplete |
Підказка браузеру для автозаповнення ("name", "email", "tel")
|