---
title: "Write headings and labels that say what · Agent Wranglers"
url: https://agentwranglers.se/playbook/accessibility/structure-and-names/descriptive-headings
id: AXS-75
level: Recommended
updated: 2026-10-27
build: a2a6bdfed830
tokens: 816
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Write headings and labels that say what follows

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Structure and names](https://agentwranglers.se/playbook/accessibility/structure-and-names.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers.md). Updated 2026-10-27.

- ID: AXS-75
- Level: Recommended
- Chapter: [Structure and names](https://agentwranglers.se/playbook/accessibility/structure-and-names.md)
- Rule: Make every heading name the section under it, and every label name its field. Keep heading levels in order, one `h1` per page and no skipped levels going down. This is WCAG criterion 2.4.6 (AA).
- Check: axe `heading-order`, `page-has-heading-one` and `empty-heading` pass. A test fails on any heading or label whose text is only "More", "Details", "Info", "Section" with a number, or one character.
- How: Screen reader users jump from heading to heading to scan a page, as sighted people skim. Headings such as "More" or "Section 2" tell them nothing. Use the words people look for, such as "Delivery times" or "Cancel your plan". Pick the level by place in the outline, not by font size, and style it in CSS. Labels follow [Label every form field](https://agentwranglers.se/playbook/accessibility/forms-changes-and-time/form-labels.md).

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### HTML example

```html
<h1>Your order</h1>
<h2>Delivery times</h2>
<h2>Cancel your order</h2>
```

### JavaScript example

```js
const VAGUE = /^(more|details|info|section \d+|.)$/i;
const texts = await page.locator('h1, h2, h3, h4, h5, h6, label').allInnerTexts();
expect(texts.filter(t => VAGUE.test(t.trim()))).toEqual([]);
```

### Python example

```python
VAGUE = re.compile(r"^(more|details|info|section \d+|.)$", re.I)
texts = page.locator("h1, h2, h3, h4, h5, h6, label").all_inner_texts()
assert [t for t in texts if VAGUE.match(t.strip())] == []
```

## Sources

- [WCAG 2.2 – 2.4.6 Headings and Labels](https://www.w3.org/TR/WCAG22/#headings-and-labels)
- [W3C WAI – Headings tutorial](https://www.w3.org/WAI/tutorials/page-structure/headings/)

## Related rules

- AXS-27 [Label every form field](https://agentwranglers.se/playbook/accessibility/forms-changes-and-time/form-labels.md) in Accessibility

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/accessibility/structure-and-names/descriptive-headings">Agent Wranglers accessibility playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Title every view and mark each language change](https://agentwranglers.se/playbook/accessibility/structure-and-names/view-title-and-language.md)
- Next: [Use ARIA only for what HTML cannot say](https://agentwranglers.se/playbook/accessibility/structure-and-names/aria-usage.md)
- [Structure and names](https://agentwranglers.se/playbook/accessibility/structure-and-names.md)
