Headings and labels should tell people what a section or field is for. Vague text such as Date, Info or Go slows everyone and blocks some users.
Headings let people scan, and let screen reader users jump from section to section. Labels tell people what to type or choose. If three fields are all labelled "Date", or sections are titled "Information" and "Other", people have to guess.
Success Criterion 2.4.6 says headings and labels describe topic or purpose. It applies only if headings or labels exist; it does not require you to add them. A short word can pass if it is an appropriate cue, and an icon can work as a label when its meaning is commonly understood in context, such as a magnifying glass next to a search field.
Related criteria cover other parts: 1.3.1 for correct markup, 3.3.2 for labels on inputs, and 4.1.2 for how names are exposed. This one is about the words.
The people affected include those who navigate by headings or by a list of form fields, and anyone filling in a form for a service they only use once a year.
When a form has several fields of the same type, each label has to say which one it is.
<label for="d1">Date</label> <input id="d1" type="date">
<label for="d2">Date</label> <input id="d2" type="date">
<label for="d3">Date</label> <input id="d3" type="date"><label for="d1">Date of incident</label> <input id="d1" type="date">
<label for="d2">Date you noticed the damage</label> <input id="d2" type="date">
<label for="d3">Preferred inspection date</label> <input id="d3" type="date">A heading should describe what follows, in words a resident would use.
<h2>Welcome!</h2>
<h2>Next</h2>
<h2>Final</h2><h2>Who can enroll</h2>
<h2>Documents to bring</h2>
<h2>Deadlines and fees</h2>A dialog's name should be its heading, and a button should say what it does.
<dialog aria-label="Dialog">
<p>Cancel reservation?</p>
<button>Go</button>
</dialog><dialog aria-labelledby="dlg-title">
<h2 id="dlg-title">Cancel your reservation</h2>
<button type="button">Yes, cancel reservation</button>
<button type="button">Keep reservation</button>
</dialog>SwiftUI:
Form {
TextField("Info", text: $incidentDate)
}Form {
Section("Incident details") {
TextField("Date of incident", text: $incidentDate)
}
}Jetpack Compose:
OutlinedTextField(
value = date, onValueChange = { date = it },
label = { Text("Field") }
)Text("Incident details", Modifier.semantics { heading() })
OutlinedTextField(
value = date, onValueChange = { date = it },
label = { Text("Date of incident (MM/DD/YYYY)") }
)A tool can tell you that a label exists. Only a person can tell you whether it makes sense.
Ship it when each heading, field label and button, read on its own, describes its topic or purpose. Forms are a good place to start the review.