heading-quality
Heading text should be descriptive, not a placeholder
Flags headings whose accessible name is a placeholder rather than a description of the content that follows: a generic word ("Heading", "Untitled"), a numbered template slot ("Section 2"), a filename, or a URL. English phrases are always recognized, and German, Spanish, French or Japanese ones when the heading is in that language.
Applies to. Elements with a heading role (native <h1>-<h6>, or any element whose role attribute resolves to heading: the first token naming a known role, matched case-insensitively) that are included in the accessibility tree and have a non-empty accessible name. A heading with no name at all is empty-heading's concern, not this rule's. A custom element whose ElementInternals give it the heading role (this.attachInternals().role), with no role attribute naming another, counts as a native element with that role does.
Expectation. The heading's accessible name, normalized (whitespace-collapsed, case-folded, trailing punctuation stripped), is not a placeholder left in the markup: a known generic word ("heading", "title", "untitled", "lorem ipsum", ...), a numbered template slot ("Heading 2", "Section 3"), a filename, or a URL. None of these describe the topic or purpose of the content they introduce.
What a finding reports.
name: the heading's accessible name, with whitespace collapsed.normalizedName: the same name as it was matched: lower case, with trailing punctuation removed.
These data.details fields help to read and reproduce a finding. Apart from reasonCode and the few fields Output schema names as stable, they are not a stable contract: a field may be renamed or dropped in a minor release, so don’t build on them.
Examples
<h3>Heading</h3><p>We are open Monday through Friday from 10 to 16.</p>
The heading text is the generic placeholder word "Heading" itself, not a description of the section.
<h3>Opening hours</h3><p>We are open Monday through Friday from 10 to 16.</p>
The heading names its actual topic.
How to check
When this rule can’t decide, it reports cantTell and leaves the question to a person. Each question it can ask is listed here under its reason code, with the steps to answer it. A finding carries the same steps as howToCheck, in the scan’s language. See Output schema.
FILENAME_LIKE_HEADING
- Find the heading the report names and read its text.
- Read the content that follows it, up to the next heading.
- Decide whether that file is the subject of the section (a file offered for download) or a leftover name such as an image's file name.
Pass. The file name is the real subject of the section, such as the document it offers.
Fail. The heading is a leftover file name (such as IMG_1234.jpg) that does not describe the content after it, which fails WCAG 2.4.6 (G130).
PLACEHOLDER_HEADING_TEXT
- Find the heading the report names and read its text.
- Read the content that follows it, up to the next heading.
- Decide whether the heading describes that content or is template text such as "Heading", "Lorem ipsum" or "Untitled".
Pass. The heading names the topic of the content after it (a numbered "Step 1" over the first step is fine).
Fail. The heading is placeholder text that does not describe the content after it, which fails WCAG 2.4.6 (G130).
URL_LIKE_HEADING
- Find the heading the report names and read its text.
- Read the content that follows it, up to the next heading.
- Decide whether the web address is the subject of that section (a site being reviewed or listed) or stands in for a real title.
Pass. The address is the topic of the section, so it describes the content after it.
Fail. The address does not describe the content after it, which fails WCAG 2.4.6 (G130).