# Markup is valid and well-formed

- **Pattern:** `ab-000126` (`accessibility-wcag.understandable.valid-markup`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000126
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000126)

## Why it matters

Invalid HTML — duplicate IDs, improperly nested elements, unclosed tags — causes screen readers to parse the DOM incorrectly or skip content entirely. WCAG 2.2 SC 4.1.1 (Parsing) is a Level A requirement. Duplicate `id` values break `aria-labelledby`, `aria-describedby`, and `for` associations — the very attributes that connect form labels to inputs and error messages to fields. A heading nested inside a `<button>` confuses the accessibility tree in ways that vary unpredictably across screen readers.

## Severity rationale

Low because markup errors produce inconsistent rather than universal failures — different browsers and AT combinations are affected differently — but duplicate IDs break ARIA relationships globally throughout the page, violating WCAG 2.2 SC 4.1.1 at Level A.

## Remediation

Run automated HTML validation as part of your CI pipeline to catch duplicate IDs and nesting errors before they reach production.

```bash
# Install htmlhint as a dev dependency
npm install --save-dev htmlhint

# Add to package.json scripts
"lint:html": "htmlhint 'src/**/*.html' 'public/**/*.html'"

# Or use Nu Validator for rendered output in CI
npx @nicolo-ribaudo/nuhtml-check http://localhost:3000
```

For React/JSX specifically, duplicate `id` values are the most common violation. Search the codebase for hardcoded `id=` strings that appear more than once — every duplicate breaks any ARIA attribute referencing that ID. Also check for `<div>` or `<p>` inside `<button>` and `<p>` inside `<p>`, which are invalid nesting patterns that corrupt the accessibility tree.

## Detection

- **ID:** `valid-markup`
- **Severity:** `low`
- **What to look for:** Enumerate every relevant item. Check for common HTML validity issues: duplicate IDs, improper nesting (e.g., `<p>` inside `<p>`, `<div>` inside `<button>`), missing closing tags, malformed attributes.
- **Pass criteria:** At least 1 of the following conditions is met. Markup is valid per HTML5 spec. No duplicate IDs. Elements properly nested. All tags closed.
- **Fail criteria:** Markup has duplicate IDs, improper nesting, or unclosed tags.
- **Skip (N/A) when:** Never — valid markup applies to all HTML documents.
- **Detail on fail:** Example: `"Multiple elements with id='nav-menu'. Button contains a div. Unclosed span tags"`
- **Remediation:** Validate HTML with W3C Nu Validator or build-time tools:

  ```bash
  # Install in CI
  npm install --save-dev htmlhint

  # Run validation
  htmlhint "src/**/*.html"
  ```

  Or use VS Code extension: "HTML Hint" to check in real-time.

## External references

- wcag 4.1.1
- section-508 501.1

Taxons: accessibility

HTML version: https://auditbuffet.com/patterns/ab-000126
