Forms - Fieldsets
NOTE:
- New to accessibility or uncertain of requirements, it will be helpful to review all sections below.
- Already familiar with requirements, skip to the “Working Example” section for sample HTML, CSS and JavaScript (when needed), along with a working demo.
- Grouping related form controls makes it easier to understand forms for all users.
- Grouping helps to add a logical structure to the forms.
-
Form controls CAN be grouped together based on the topic, functionality or
interdependency.
-
Topic: Related form controls to the same topic or subject matter.
For example, personal information fields such as name, address, and email. -
Functionality: Serving the same functional purpose.
For example, fields for selecting a date range. -
Interdependency: Form controls with interdependent relationships.
For example, form controls for selecting a country and then a state.
-
Topic: Related form controls to the same topic or subject matter.
- In the case of lengthy forms, it helps people to focus on smaller and more manageable groups rather than try to grasp the entire form at once.
- Avoid nesting of grouping elements programmatically.
- DO NOT use grouping unnecessarily for a single form control.
-
The native HTML
<fieldset>
and<legend>
elements are specified for grouping the form controls.- The
<fieldset>
element is provided as a container for related form controls. -
The
<legend>
element is provided to contain the text that acts as an accessible name as well as a visual label to identify the group. -
Grouping using HTML
<fieldset>
and<legend>
elements is the most robust technique. -
As a best practice the
<legend>
element SHOULD consist of the visible text that will serve as a visual label and an accessible name for the group. -
A
<legend>
element can consist of heading elements such as<h1>
,<h2>
,<h3>
and so on to denote the text that describes the section name as well as acts as visual label and accessible name for the group of form controls. -
Visually a boxed border gets added when form controls are grouped using
<fieldset>
and<legend>
elements.- CSS techniques CAN be used to hide the border and keep the visual presentation intact.
-
Color contrast ratio requirements MUST be met for the visual label of the
group.
- Minimum ratio of 4.5:1 MUST be met for the visual label having standard text size.
- Minimum ratio of 3:1 MUST be met for visual label text having larger text size i.e., 14pts with bold weight or more than 18 pts.
- Alternatively, ARIA CAN be used as described in the respective sections of Grouping – Checkbox, Radio Buttons and Related Fields.
- The
- Related checkboxes in a form SHOULD be grouped with the respective visible text that acts as a visual label as well as accessible name. This helps screen reader users to understand the purpose of the checkboxes effectively.
- Checkboxes CAN be grouped either using native HTML elements or using ARIA.
-
Native HTML
<fieldset>
element SHOULD be used to group the related checkboxes. -
The
<legend>
element SHOULD consist of the visible text that will serve as a visual label as well as an accessible name for the group. -
The visual label in
<legend>
element CAN be placed off-screen in case of design constraint using CSS techniques.
For example,
<fieldset>
<legend> Food Allergies: </legend>
<input id="milk" type="checkbox" name="allergies" value="milk">
<label for="milk"> Milk </label><br>
<input id="egg" type="checkbox" name="allergies" value="egg">
<label for="egg"> Egg </label><br>
<input id="peanut" type="checkbox" name="allergies" value="peanut">
<label for="peanut"> Peanut </label><br>
<input id="wheat" type="checkbox" name="allergies" value="wheat">
<label for="wheat"> Wheat </label><br>
</fieldset>
Though ARIA CAN be used as an alternative, it is advisable to use correct semantic HTML element since native elements have out of the box accessibility.
-
Checkboxes CAN also be grouped by specifying
role="group"
on the parent containers. - To provide an accessible name for the group aria-label attribute SHOULD be used.
- Alternatively, in case where visible text is present to specify the visual group label, an aria-labelledby attribute SHOULD be used by referencing the value of id attribute of the of visible text container.
For example,
<div role="group" aria-labelledby="id1">
<div id="id1"> Food Allergies: </div>
<input id="milk" type="checkbox" name="allergies" value="milk">
<label for="milk"> Milk </label><br>
<input id="egg" type="checkbox" name="allergies" value="egg">
<label for="egg"> Egg </label><br>
<input id="peanut" type="checkbox" name="allergies" value="peanut">
<label for="peanut"> Peanut </label><br>
<input id="wheat" type="checkbox" name="allergies" value="wheat">
<label for="wheat"> Wheat </label><br>
</div>
A form with programmatically grouped form controls benefits users with:
- People with cognitive disabilities
- People using speech input
- People using screen readers
- People using keyboard only
<fieldset class="address">
<legend><strong>Student Details</strong></legend>
<div>
<label for="student_fname">
<span class="visuallyhidden">Student </span>First Name:
</label><br>
<input type="text" name="student_fname" autocomplete="given-name" id="student_fname">
</div>
<div>
<label for="student_lname">Last Name:</label><br>
<input type="text" name="student_lname" autocomplete="family-name" id="student_lname">
</div>
<div>
<label for="student_number">Phone:</label><br>
<input type="text" name="student_number" autocomplete="tel" id="student_number">
</div>
<div>
<label for="student_city">City:</label><br>
<input type="text" name="student_city" id="student_city">
</div>
<div>
<label for="student_zip">ZIP code:</label><br>
<input type="text" name="student_zip" autocomplete="postal-code" id="student_zip">
</div>
</fieldset>
<fieldset class="address">
<legend><strong>Teacher Details</strong></legend>
<div>
<label for="teacher_fname">
<span class="visuallyhidden">Teacher </span>First Name:
</label><br>
<input type="text" name="teacher_fname" autocomplete="given-name" id="teacher_fname">
</div>
<div>
<label for="teacher_lname">Last Name:</label><br>
<input type="text" name="teacher_lname" autocomplete="family-name" id="teacher_lname">
</div>
<div>
<label for="teacher_number">Phone:</label><br>
<input type="text" name="teacher_number" autocomplete="tel" id="teacher_number">
</div>
<div>
<label for="teacher_city">City:</label><br>
<input type="text" name="teacher_city" id="teacher_city">
</div>
<div>
<label for="teacher_zip">ZIP code:</label><br>
<input type="text" name="teacher_zip" autocomplete="postal-code" id="teacher_zip">
</div>
</fieldset>
.address {
display: inline;
width: 40%;
}
.visuallyhidden {
clip: rect(0 0 0 0);
clip-path: inset(50%);
overflow: hidden;
position: absolute;
}
input[type=text] {
display: block;
margin-bottom: 0.2rem;
padding: 0.4rem;
border: 1px solid #8e8e8e;
line-height: 1.15;
width: 90%;
}