# Heading Hierarchy

Logical heading levels, descriptive headings, never skip levels.

## Criteria

| Standard | Criteria                       |
| -------- | ------------------------------ |
| WCAG 2.2 | 2.4.6 Headings and Labels (AA) |
| RGAA 4.1 | 9.1 Heading hierarchy          |

### Headings and Labels — WCAG 2.4.6 (AA) / RGAA 9.1

Headings and labels must describe topic or purpose. Heading hierarchy must not skip levels (no `<h1>` → `<h3>`). Content of headings must be relevant. Use `<h1>`–`<h6>` or `role="heading"` with `aria-level`.

### RGAA 9.1 — Heading structure (Level A/AA)

Is information structured through appropriate use of headings?

#### Test 9.1.1 — Heading hierarchy is relevant

Is the hierarchy between headings (`<hx>` or elements with `role="heading"` + `aria-level`) relevant?

Methodology:

1. Find all headings in the document (`<hx>` tags or elements with `role="heading"` + `aria-level`).
2. Verify the hierarchy between headings is relevant (no skipped levels, logical nesting).
3. If so, the test is validated.

#### Test 9.1.2 — Heading content is relevant

Is the content of each heading relevant?

Methodology:

1. For each heading identified in test 9.1.1, verify its content is relevant (describes the topic or purpose of the section it introduces).
2. If so for every heading, the test is validated.

#### Test 9.1.3 — Headings use proper markup

Is each text passage constituting a heading structured with an `<hx>` tag or a tag with `role="heading"` + `aria-level`?

Methodology:

1. For each heading identified in test 9.1.1, verify that:
   - Either it uses an `<hx>` tag (where x is a value between 1 and 6);
   - Or it uses an element with `role="heading"` and `aria-level=x` (where x is a numeric value).
2. If so for every heading, the test is validated.

#### Notes techniques

WAI-ARIA allows defining headings via the `heading` role and the `aria-level` attribute (indicating heading level). Although native HTML `<hx>` elements are preferred, the WAI-ARIA `role="heading"` is compatible with accessibility.

#### WCAG references

- 1.3.1 Info and Relationships (A)
- 2.4.1 Bypass Blocks (A)
- 2.4.6 Headings and Labels (AA)
- 4.1.2 Name, Role, Value (A)

## Patterns

```html
<!-- BAD: skips h2 -->
<h1>Page Title</h1>
<h3>Subsection</h3>

<!-- GOOD: sequential levels -->
<h1>Page Title</h1>
<h2>Section</h2>
<h3>Subsection</h3>
<h2>Another Section</h2>
```

**Shopify** — dynamic h1 based on section position:

```liquid
{%- assign title_tag = 'h2' -%}
{%- if section.index0 == 0 -%}
  {%- assign title_tag = 'h1' -%}
{%- endif -%}

<{{ title_tag }}>{{ section.settings.title }}</{{ title_tag }}>
```

**React** — flexible heading component:

```tsx
function Heading({ level, children }: { level: 1 | 2 | 3 | 4 | 5 | 6; children: React.ReactNode }) {
  const Tag = `h${level}` as keyof JSX.IntrinsicElements
  return <Tag>{children}</Tag>
}
```
