Тег fieldset (от английского field set, «набор полей») объединяет связанные поля формы в одну группу. Браузер рисует вокруг группы рамку, программы чтения с экрана воспринимают её как группу, а атрибут disabled у fieldset отключает сразу все поля внутри. Заголовок группы задаёт тег legend, он записывается первым, а закрывающий тег </fieldset> обязателен.
Группа работает внутри тега form, объединяет поля из тега input и других тегов, а надписи к полям задаёт тег label. Основы разобраны в уроке «Группировка полей формы в HTML: тег fieldset».
<fieldset>
<legend>Получение</legend>
<label><input type="radio" name="delivery" value="courier"> Курьер</label>
<label><input type="radio" name="delivery" value="post"> Почта</label>
</fieldset>
В этой статье
- Тег fieldset в HTML: что это и для чего нужен
- Заголовок группы: legend внутри fieldset
- Атрибут disabled: отключение всех полей группы
- Атрибуты name и form: что даёт fieldset форме
- Вложенные fieldset и допустимое содержимое
- Тег fieldset и JavaScript: elements, disabled и проверка
- CSS для fieldset: рамка, отступы и flex
- Доступность fieldset: название группы и radiogroup
- Атрибуты тега fieldset
- Вопросы про тег fieldset: переключатель группы и ширина
- Частые ошибки с тегом fieldset
Тег fieldset в HTML: что это и для чего нужен
Группа нужна для трёх целей. Визуально рамка отделяет связанные поля от остальных. Для программ чтения с экрана поля внутри fieldset относятся к одной группе, и она получает название. Технически одним атрибутом disabled отключается всё содержимое. Рамка по умолчанию зависит от браузера и системы, а оформляется обычными свойствами CSS. Тег записывают чаще всего внутри form, но обязательным это не является.
<fieldset>
<legend>Контакты</legend>
<input name="email" type="email">
<input name="phone" type="tel">
</fieldset>
Пример: группа полей с fieldset и без него
Выберите запись и отметьте переключатель: под результатом рамка и состояние группы.
Заголовок группы: legend внутри fieldset
Заголовок группы задаёт legend. Он записывается первым внутри fieldset, и браузер размещает его на верхней рамке. У него две роли: он служит названием группы для программ чтения, а поля внутри первого legend остаются доступными, когда группа отключена. Внутри допустимы текст, строчные теги, поле формы и заголовок h3.
<fieldset disabled>
<legend><label><input type="checkbox" name="on"> Включить</label></legend>
<input name="city">
</fieldset>
Пример: заголовок и поле в legend
Выберите запись: под результатом состояние полей группы.
Атрибут disabled: отключение всех полей группы
Атрибут disabled отключает все поля внутри группы: input, select, textarea и button. Исключение: поля в первом legend. У отключённого поля селектор :disabled совпадает, а собственное свойство disabled остаётся false, поэтому скрипт, читающий свойство поля, отключения не увидит. Атрибут булев: disabled="false" группу всё равно отключает, а снять отключение можно, удалив атрибут или присвоив fieldset.disabled = false. Отключённые поля не получают клики и в данные формы не попадают. Ссылка a полем формы не является и работает как обычно. Вложенный fieldset отключается вместе с внешним.
<fieldset disabled>
<legend>Адрес</legend>
<input name="city">
<button type="button">Кнопка</button>
</fieldset>
Пример: что отключает disabled
Выберите запись и кликните по кнопке и ссылке: под результатом состояние полей и число кликов.
Атрибуты name и form: что даёт fieldset форме
Атрибут name у fieldset в данные формы не попадает: на сервер уходят только значения полей. Зато сам fieldset входит в form.elements, и form.elements.address возвращает его. Атрибут form связывает с формой сам fieldset, записанный вне неё, но поля внутри форму от него не получают: каждому полю нужен свой form. Подробнее об атрибуте у полей: атрибут form у поля.
<form id="order"></form>
<fieldset name="address" form="order">
<input name="city" form="order">
</fieldset>
Пример: name, form и данные формы
Выберите запись: под результатом связь с формой и данные.
Вложенные fieldset и допустимое содержимое
Внутри fieldset допустим обычный контент страницы: текст, div, абзацы, таблицы и вложенные fieldset. Вложенность удобна для сложных форм: внешняя группа «Адрес» и внутренняя «Индекс». Отключение внешней группы действует и на вложенную. Сам fieldset нельзя записывать внутри p: браузер закрывает абзац перед группой, а закрывающий </p> создаёт лишний пустой абзац. Проверка HTML в этом случае сообщает об ошибке.
<fieldset>
<legend>Адрес</legend>
<fieldset>
<legend>Индекс</legend>
<input name="zip">
</fieldset>
</fieldset>
Пример: вложенные группы и fieldset внутри p
Выберите запись: под результатом родитель группы и число абзацев.
Тег fieldset и JavaScript: elements, disabled и проверка
Список полей группы возвращает fieldset.elements: в него входят поля, кнопки, select, output, вложенные fieldset и поля внутри legend, а обычные теги вроде span не входят. Свойство type у fieldset всегда равно fieldset, а disabled читает и меняет атрибут. Отключённая группа в проверке формы не участвует: required у полей внутри не проверяется, и form.checkValidity() возвращает true. Сам fieldset проверяемым не бывает: willValidate равен false.
const form = document.querySelector("form");
const fieldset = document.querySelector("fieldset");
console.log(fieldset.elements.length);
fieldset.disabled = true;
console.log(form.checkValidity());
Пример: elements, type, disabled и проверка
Выберите запись: под результатом ответ скрипта.
CSS для fieldset: рамка, отступы и flex
Рамку, отступы и заголовок оформляют обычными свойствами: border, border-radius и padding. Чтобы убрать рамку, а смысловую группу сохранить, пишут border: 0; padding: 0; margin: 0. Для расположения полей fieldset принимает display: flex и display: grid, а заголовок остаётся на рамке. Состояния группы описывают селекторы fieldset:disabled и fieldset:has(:invalid).
fieldset {
border: 1px solid #1c9e93;
border-radius: 8px;
padding: 12px;
}
fieldset:disabled {
opacity: 0.5;
}
Пример: рамка, flex, grid и :has()
Выберите стиль: под результатом вычисленные display и рамка.
Доступность fieldset: название группы и radiogroup
У fieldset неявная роль group, а название берётся из legend. Приоритет такой: aria-labelledby главнее aria-label, а он главнее legend. Без legend и других подписей группа остаётся без названия. Для группы переключателей допустима роль radiogroup, а другие роли вроде menu проверка HTML считает ошибкой. Если у блока переключателей есть вопрос, его записывают в legend: без него программа чтения зачитывает варианты без вопроса.
<fieldset aria-label="Способ">
<legend>Получение</legend>
<label><input type="radio" name="d"> Курьер</label>
</fieldset>
Пример: откуда берётся название группы
Выберите запись: под результатом роль и название группы.
Атрибуты тега fieldset
У fieldset три собственных атрибута и глобальные. Отдельно отмечены атрибуты, которых у fieldset нет: часть из них знакома по полям формы, но проверка HTML сообщает об ошибке.
| Атрибут | Статус | Что делает | Пример записи |
|---|---|---|---|
disabled | актуален | Отключает все поля внутри, кроме полей в первом legend | disabled |
form | актуален | id формы, с которой связан сам fieldset, поля внутри форму не получают | form="order" |
name | актуален | Название группы для form.elements, на сервер не уходит | name="address" |
class | глобальный | Класс для оформления | class="group" |
id | глобальный | Идентификатор группы, например для aria-labelledby | id="delivery" |
title | глобальный | Всплывающая подсказка | title="Получение" |
role | глобальный | Допустимы group, radiogroup, presentation и none | role="radiogroup" |
value | не существует | У группы нет значения | value="1" |
type | не существует | Тип у группы не задают | type="radio" |
readonly | не существует | Запрет правки задают у самих полей | readonly |
placeholder | не существует | Подсказку задают полю | placeholder="Адрес" |
Вопросы про тег fieldset: переключатель группы и ширина
Группу с рабочим переключателем отключают особым способом, а рамка в узком контейнере нередко выступает за его границы: как отключить группу с рабочим переключателем и почему рамка выступает за границы контейнера.
Как отключить группу полей, но сохранить один рабочий переключатель?
Переключатель помещают в первый legend, а группу включают из скрипта. Поле внутри legend вместе с группой не отключается, поэтому флажок остаётся доступным, а обработчик change добавляет и убирает атрибут disabled у fieldset. Флажок внутри самой группы после отключения включить не сможет.
<fieldset disabled>
<legend>
<label><input type="checkbox"> Нужен курьер</label>
</legend>
<input name="city" placeholder="Город">
</fieldset>
Пример: флажок в legend, в группе и снаружи
Выберите запись и отметьте флажок: под результатом состояние флажка и поля.
Почему fieldset выступает за границы узкого контейнера?
У fieldset по умолчанию задан min-width: min-content: группа не сужается меньше ширины содержимого. Если внутри широкое поле, рамка становится шире контейнера. Исправляют это значением min-width: 0 у fieldset и max-width: 100% у поля.
fieldset {
min-width: 0;
}
input {
max-width: 100%;
}
Пример: ширина группы в узком контейнере
Выберите запись: под результатом ширина контейнера, группы и поля.
Частые ошибки с тегом fieldset
Ошибки с группой чаще всего связаны с заголовком, вложенностью и ожиданиями от отключения.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
Блок переключателей без fieldset и legend | Программа чтения зачитывает варианты без вопроса | Обернуть группу в fieldset и записать вопрос в legend |
legend не первым или второй legend | Запись недопустима, проверка HTML сообщает об ошибке | Записать один legend первым |
Блочный тег, например div, внутри legend | Запись недопустима, проверка HTML сообщает об ошибке | Использовать текст, span или заголовок |
fieldset внутри p | Абзац закрывается перед группой, появляется лишний пустой абзац | Заменить p на div |
disabled="false" для включения группы | Булев атрибут действует по наличию, группа остаётся отключённой | Удалить атрибут или присвоить fieldset.disabled = false |
Расчёт на то, что name у fieldset уйдёт на сервер | В данные попадают только значения полей | Дать name самим полям |
form только у fieldset | Поля внутри форму не получают и не отправляются | Указать form у каждого поля или записать группу внутри form |
disabled там, где значения нужно отправить | Отключённые поля в данные не попадают | Использовать readonly у текстовых полей |
| Флажок, который включает группу, записан внутри этой группы | Он отключается вместе с группой, и включить её нечем | Поместить выключатель в первый legend или вне группы |