git clone https://github.com/Intense-Visions/harness-engineering
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/claude-code/a11y-semantic-html" ~/.claude/skills/intense-visions-harness-engineering-a11y-semantic-html && rm -rf "$T"
agents/skills/claude-code/a11y-semantic-html/SKILL.mdSemantic HTML for Accessibility
Use semantic HTML elements to convey document structure, meaning, and navigation landmarks to assistive technology
When to Use
- Building any user-facing web page or component
- Replacing
and<div>
soup with meaningful elements<span> - Structuring page landmarks for screen reader navigation
- Ensuring heading hierarchy is logical and complete
- Reviewing existing markup for accessibility improvements
Instructions
- Use landmark elements to define page regions. Screen readers expose landmarks as a navigation menu, letting users jump directly to the section they need.
<header>Site branding and primary navigation</header> <nav aria-label="Main">Primary navigation links</nav> <main>Primary page content — exactly one per page</main> <aside>Complementary content (sidebar, related links)</aside> <footer>Site footer, legal links, copyright</footer>
- Use exactly one
per page.<main> - Use
to distinguish multiplearia-label
elements (e.g., "Main", "Footer", "Breadcrumb").<nav> - Do not nest landmarks unnecessarily —
inside<nav>
is fine,<header>
inside<main>
is not.<main>
- Use headings (
-<h1>
) to create a logical outline. Headings are the primary way screen reader users scan a page. Follow a strict hierarchy — do not skip levels.<h6>
<h1>Product Catalog</h1> <h2>Electronics</h2> <h3>Laptops</h3> <h3>Phones</h3> <h2>Clothing</h2> <h3>Men's</h3> <h3>Women's</h3>
- One
per page (the page title).<h1> - Do not use headings for visual styling — use CSS classes instead.
- Do not skip from
to<h2>
— screen readers announce heading levels.<h4>
- Use
for actions and<button>
for navigation. Buttons trigger in-page actions (submit, toggle, open modal). Links navigate to a URL. Do not use<a>
for either.<div onclick>
// Correct — button for action <button onClick={handleSave}>Save Changes</button> // Correct — link for navigation <a href="/settings">Go to Settings</a> // Wrong — div pretending to be interactive <div onClick={handleSave} className="btn">Save Changes</div>
-
Use
,<ul>
, and<ol>
for lists. Screen readers announce "list, 5 items" — giving users context about the content structure. Navigation menus should be<dl>
inside<ul>
.<nav> -
Use
for tabular data, never for layout. Include<table>
,<thead>
, and<th scope="col">
so screen readers can associate data cells with headers.<th scope="row">
<table> <caption> Quarterly Sales </caption> <thead> <tr> <th scope="col">Region</th> <th scope="col">Q1</th> <th scope="col">Q2</th> </tr> </thead> <tbody> <tr> <th scope="row">North</th> <td>$1.2M</td> <td>$1.4M</td> </tr> </tbody> </table>
-
Use
,<form>
, and<fieldset>
for form structure. Group related inputs with<legend>
and provide a group label with<fieldset>
.<legend> -
Use
for self-contained content that makes sense independently (blog posts, comments, product cards). Use<article>
for thematic grouping within a page — always pair<section>
with a heading.<section> -
Use
for dates and durations to provide machine-readable time data.<time>
<time datetime="2026-04-07">April 7, 2026</time>
- Use
and<details>
for expandable content instead of custom JavaScript accordions. They are natively accessible with keyboard and screen reader support.<summary>
<details> <summary>Order details</summary> <p>Order #12345 — shipped on April 5, 2026.</p> </details>
- Validate your HTML structure. Run the W3C validator and check the document outline. A well-structured document should make sense when read as a heading-only outline.
Details
Why semantic HTML matters: Assistive technology (screen readers, switch controls, voice navigation) relies on the HTML element type to determine how to present and interact with content. A
<button> is announced as "button" and activated with Enter/Space. A <div> with an onClick is announced as "group" — the user has no idea it is interactive.
Implicit ARIA roles: Semantic elements carry implicit ARIA roles —
<nav> is role="navigation", <main> is role="main", <button> is role="button". Using semantic HTML means you rarely need to add ARIA attributes manually.
Common anti-patterns:
instead of<div class="header"><header>- Using
because it looks the right size (use CSS for sizing)<h3>
— if it does not navigate, use<a href="#" onclick={fn}><button>
for spacing instead of CSS margin/padding<br>
and<b>
for styling — use<i>
and<strong>
for semantic emphasis, CSS for visual styling<em>
Testing: Use the browser's accessibility tree inspector (Chrome DevTools > Accessibility tab) to see how your markup is exposed to assistive technology. The rendered accessibility tree should mirror the visual hierarchy.
Source
https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.