Тег fieldset объединяет несколько связанных полей формы в одну группу, а legend даёт этой группе подпись. Браузер по умолчанию рисует вокруг группы рамку - но главная польза не в рамке: программа для незрячих объявляет подпись legend при переходе к любому полю внутри группы, и так подпись не нужно повторять у каждого поля отдельно.
Попробуй кликнуть по варианту "Самовывоз" - ничего не произойдёт, поля отключены атрибутом disabled у fieldset. Теперь удали disabled из первой строки кода и попробуй снова - поля оживут.
Группировка полей формы в HTML: тег fieldset
Тег fieldset визуально и логически объединяет несколько related полей формы - например, отдельный блок "Адрес доставки" внутри большой формы заказа. У него есть удобный побочный эффект: атрибут disabled на самом fieldset сразу отключает ВСЕ вложенные поля - не нужно прописывать disabled у каждого input по отдельности.
<fieldset><legend>Контактные данные</legend>...</fieldset> - логическая группа реально связанных полей, которая имеет смысл и без рамки.
<fieldset>Просто текст без полей формы</fieldset> - fieldset существует для группировки ПОЛЕЙ ФОРМЫ, а не для рисования рамки вокруг произвольного контента; для этого есть обычный div.
Подпись группы полей в HTML: тег legend
legend - это подпись для fieldset, и по спецификации он должен идти первым дочерним элементом внутри fieldset. Именно текст legend становится тем, что программа для незрячих объявляет как название группы при переходе к любому полю внутри неё - это и есть главная причина использовать fieldset/legend вместо обычных div и label без общей подписи.
<fieldset><legend>Способ оплаты</legend><label>...</label></fieldset> - legend идёт сразу первым внутри fieldset, как того требует спецификация.
<fieldset><div><legend>Способ оплаты</legend></div></fieldset> - legend обёрнут в дополнительный div и больше не является первым РЕАЛЬНЫМ дочерним элементом fieldset, из-за чего связь "подпись для группы" может не распознаваться.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Использовать fieldset только ради рамки вокруг произвольного контента | Приходится потом бороться с рамкой и отступами через CSS вместо использования подходящего тега | fieldset - для группы полей формы; для визуальной рамки без смысла формы использовать div |
| Оборачивать legend в дополнительный тег (например, div) | legend перестаёт быть первым РЕАЛЬНЫМ дочерним элементом fieldset - связь "подпись для группы" может не распознаваться | Стилизовать legend напрямую через CSS, не оборачивая его в другой элемент |
| Считать, что disabled на внешнем fieldset защищает legend вложенного внутреннего fieldset | Исключение "поля внутри legend не отключаются" действует только для СОБСТВЕННОГО legend каждого fieldset - вложенный legend не защищён от внешнего disabled | Проверять поведение вложенных fieldset отдельно, не полагаясь на автоматическую защиту |
Шпаргалка
| Термин | Значение |
|---|---|
| fieldset | Группирует связанные поля формы; рамка - оформление браузера по умолчанию, не обязательный смысл |
| legend | Подпись для fieldset; должен быть первым дочерним элементом |
| disabled на fieldset | Отключает все вложенные поля, кроме полей внутри его собственного legend |
| Вложенные fieldset | Допустимы для подгрупп, но disabled внешнего не защищает legend внутреннего |
Коротко: отвечаем на вопросы
Как убрать рамку fieldset по умолчанию?
Обычным CSS, например border: none (и при желании обнулить padding). Рамка - это оформление браузера по умолчанию, а не часть смысла тега, поэтому её удаление никак не влияет на группировку полей и доступность.
Обязательно ли использовать legend внутри fieldset?
Нет, legend не обязателен - fieldset прекрасно работает и без него. Но без legend группа теряет подпись, которую озвучивают программы для незрячих, поэтому legend стоит добавлять всегда, когда у группы есть осмысленное название.
Обязан ли legend быть именно первым дочерним элементом fieldset?
По спецификации - да. На практике основные браузеры нередко снисходительны и всё равно находят legend не на первом месте, но полагаться на это не стоит: поведение может отличаться между браузерами, поэтому правильнее сразу ставить legend первым.
Почему fieldset долго "не хотел" работать с display: flex или grid?
Это был реальный и долгое время не устранённый пробел в браузерах: fieldset по умолчанию не становился настоящим flex- или grid-контейнером, свойство display будто игнорировалось. Firefox начал полноценно поддерживать это только с версии 46 (март 2016 года), другие браузеры донастроили поведение позже.