Группировка элементов формы: теги <fieldset>, <legend>, <label>
Зачем группировать элементы формы? 🤔
Форма с десятком полей — как хаотичный рынок без указателей. Пользователь теряется! Группировка решает эту проблему:
- Логическая структура — разбиваем форму на смысловые блоки (личные данные, платежи, настройки)
- Доступность — скринридеры лучше интерпретируют сгруппированные поля
- UX-улучшение — визуальное разделение снижает когнитивную нагрузку
<!-- Плохо: -->
<input type="text" placeholder="Имя">
<input type="email" placeholder="Email">
<input type="tel" placeholder="Телефон">
<!-- Хорошо: -->
<fieldset>
<legend>Контактная информация</legend>
<!-- Поля внутри -->
</fieldset>
Тег <fieldset> — создаём "загон" для полей 🏟️
Этот тег работает как контейнер для группы связанных элементов формы. Вот его суперспособности:
- Автоматическая рамка — браузер добавляет границу по умолчанию (можно кастомизировать через CSS)
- Семантика — чётко указывает браузеру и скринридерам на группу полей
- Отключение группы —
disabledна<fieldset>отключает ВСЕ вложенные поля
<fieldset>
<legend>Способ доставки</legend>
<input type="radio" id="courier" name="delivery">
<label for="courier">Курьер</label>
<input type="radio" id="pickup" name="delivery">
<label for="pickup">Самовывоз</label>
</fieldset>
<legend> — подпись для группы 🏷️
Этот тег работает как заголовок для <fieldset>. Важные нюансы:
- Всегда должен быть первым элементом внутри
<fieldset> - Поддерживает HTML-вставки (
<strong>,<span>и др.) - Позиционируется поверх границы (это можно использовать для креативных решений)
<fieldset>
<legend><span class="emoji">🌶️</span> Уровень остроты</legend>
<!-- Радио-кнопки с выбором остроты -->
</fieldset>
<label> — связываем текст и поле 🔗
Хотя <label> не относится исключительно к группировке, в формах он критически важен. Два способа использования:
- Обёртка (для чекбоксов/радио)
<label>
<input type="checkbox" name="newsletter">
Получать новости
</label>
- Атрибут
for(указывает на id элемента)
<label for="username">Логин:</label>
<input type="text" id="username">
🔥 Про-совет от Данилы Бежина: Всегда используйте <label> — это увеличивает кликабельную область и улучшает доступность. Подробнее в его видео про формы.
Практический пример: форма регистрации 🛠️
Соберём все знания в одном примере с современными приёмами:
<form>
<!-- Персональные данные -->
<fieldset class="personal-data">
<legend>Личная информация</legend>
<div class="form-group">
<label for="fullname">ФИО*</label>
<input type="text" id="fullname" required>
</div>
<div class="form-group">
<label for="birthdate">Дата рождения</label>
<input type="date" id="birthdate">
</div>
</fieldset>
<!-- Контакты -->
<fieldset>
<legend>Контакты</legend>
<div class="form-group">
<label for="phone">Телефон*</label>
<input type="tel" id="phone" required>
</div>
<div class="form-group">
<label for="email">Email*</label>
<input type="email" id="email" required>
</div>
</fieldset>
</form>
Стилизация групп через CSS 🎨
Добавим визуальной чёткости с минимальным CSS:
fieldset {
border: 2px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
legend {
padding: 0 10px;
font-weight: bold;
color: #3a86ff;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-size: 0.9em;
}
Частые ошибки и как их избежать ⚠️
-
Пустой
<fieldset>
Всегда добавляйте<legend>— это обязательный элемент для доступности. -
Не связанные
<label>
Проверяйте, что атрибутforточно соответствуетidэлемента. -
Избыточная вложенность
Не создавайте более 3 уровней вложенности<fieldset>— это усложняет восприятие.
<!-- Плохо: -->
<fieldset>
<fieldset>
<fieldset>
<!-- Три уровня — уже перебор -->
</fieldset>
</fieldset>
</fieldset>
Интерактивный чеклист 🏆
Убедитесь, что ваша форма готова к реальному использованию:
✔️ Каждая группа полей обёрнута в <fieldset> и снабжена понятным <legend>
✔️ Все <label> связаны с полями (for="..." и id="...")
✔️ Поля сгруппированы логично (например: "Контактная информация", "Оплата")
✔️ Форма корректно работает с отключёнными (disabled) элементами
✔️ Проверена доступность через скринридер (например, NVDA или VoiceOver)