agentsclimarketplace

A11y accordion

Skill xrnavigation/web-a11y-plugin/skills/a11y-accordion

Guides accessible accordion and disclosure implementation. Auto-invokes when creating accordions, collapsible sections, expandable panels, or disclosure widgets. Covers native <details>/<summary> vs ARIA accordion, the APG accordion pattern, and the disclosure pattern.From its SKILL.md

Install
npx -y skills add xrnavigation/web-a11y-plugin --skill a11y-accordion

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

11.1 KB, ~2.8k tokens by cl100k_base, as published. Nobody here has run it

Accessible Accordion & Disclosure Implementation

"No ARIA is better than Bad ARIA." — APG Read Me First

An accordion is a vertically stacked set of interactive headings, each controlling a content panel. A disclosure is simpler: a single button that shows/hides one block of content. These are different patterns with different requirements.


1. Decision: Native <details>/<summary> vs ARIA Accordion

Use this decision tree before reaching for ARIA.

SituationUseWhy
Single show/hide toggle<details>/<summary>Built-in, no JS, works without ARIA. (HTML Spec)
Independent collapsible sections, no grouping needed<details>/<summary>Progressive enhancement, works without JS.
Related sections needing group semanticsARIA accordionAdjacent <details> lack group semantics. (Roselli 2023)
Heading navigation on triggers requiredARIA accordionHeadings inside <summary> are flattened to presentational role. (Roselli 2019; O'Hara 2018)
Arrow-key navigation between headers desiredARIA accordionNative <details> only supports Enter/Space.
Complex panels with nested headings/landmarksARIA accordionrole="region" with aria-labelledby provides structure. (APG)

Hybrid approach: Start with <details>/<summary> for no-JS baseline, then enhance with JS: wrap in a container with role="group" and aria-labelledby, add exclusive-open behavior. (Roselli 2023)


2. Native <details>/<summary> Quick Reference

What It Gives You

  • Toggle behavior without JavaScript — <summary> triggers show/hide of sibling content.
  • open attribute reflects state; fires a toggle event on change.
  • name attribute for exclusive accordion — <details> elements sharing a name form a mutual-exclusion group. Opening one closes others. (MDN Blog)
<details name="faq">
  <summary>Question 1</summary>
  <p>Answer 1</p>
</details>
<details name="faq">
  <summary>Question 2</summary>
  <p>Answer 2</p>
</details>

name attribute browser support (all stable): Chrome 120+, Safari 17.2+, Firefox 130+. (Chrome for Developers)

Limitations

  1. Headings inside <summary> are flattened. <summary> maps to button role; nested headings lose heading semantics in most screen readers. (Roselli 2019)
  2. No arrow-key navigation between summaries.
  3. No grouping semantics. A set of <details> is not announced as a group.
  4. Inconsistent role announcements across screen readers. See ${CLAUDE_SKILL_DIR}/references/screen-reader-behavior.md.

Full details: ${CLAUDE_SKILL_DIR}/references/native-details-summary.md


3. Accordion vs Disclosure

CriterionDisclosureAccordion
SectionsOne (standalone)Multiple (related set)
GroupingNoneRequired (role="group" or wrapper)
Heading structureNot neededHeaders wrap triggers
Arrow-key navigationNoOptional but recommended
Mutual exclusivityNoTypically yes
Use case"Read more", help text, single FAQFAQ list, settings categories, stacked sections

"An accordion is more than a few disclosure widgets or <details>/<summary> elements one after another." — Roselli 2020

Disclosure Pattern (APG)

A button with aria-expanded that shows/hides content. No heading wrapper, no grouping, no arrow keys. (APG Disclosure Pattern)

<button aria-expanded="false" aria-controls="help-text">Help</button>
<div id="help-text" hidden>
  <p>Helpful information here.</p>
</div>

4. ARIA Accordion Pattern

Source: APG Accordion Pattern

Required Structure

<!-- WRONG — no heading, no aria-expanded, div as trigger -->
<div class="accordion">
  <div class="header" onclick="toggle()">Section 1</div>
  <div class="panel">Content</div>
</div>

<!-- RIGHT -->
<div role="group" aria-labelledby="acc-label">
  <h3 id="acc-label" class="sr-only">Frequently Asked Questions</h3>

  <h3>
    <button
      id="acc-btn-1"
      aria-expanded="false"
      aria-controls="acc-panel-1"
    >Section 1</button>
  </h3>
  <div
    id="acc-panel-1"
    role="region"
    aria-labelledby="acc-btn-1"
    hidden
  >
    <p>Panel content.</p>
  </div>
</div>

Required Attributes

AttributeElementRequirement
role="button" or native <button>Header triggerRequired
Heading element (<h2>-<h6>) or role="heading" + aria-levelWrapper around buttonRequired
aria-expanded="true/false"ButtonRequired
aria-controls="PANEL_ID"ButtonRequired
aria-disabled="true"ButtonOnly when panel cannot be collapsed
role="region"PanelOptional; avoid with 6+ panels (landmark proliferation)
aria-labelledby="BUTTON_ID"RegionRequired when role="region" is used

Structural Rules

  • The button must be the only interactive element inside the heading.
  • Native <h2>-<h6> elements are preferred over role="heading" + aria-level.
  • role="region" is useful when panels contain headings or nested interactive content, but creates landmark proliferation with many panels.

5. Keyboard Interaction Summary

KeyAccordion Behavior
Enter / SpaceToggle panel (expand/collapse)
Tab / Shift+TabStandard sequential focus navigation
Down Arrow (optional)Next header; wraps last to first
Up Arrow (optional)Previous header; wraps first to last
Home (optional)First header
End (optional)Last header

Native <details>/<summary> supports only Enter/Space and Tab. No arrow-key navigation.

Full keyboard spec: ${CLAUDE_SKILL_DIR}/references/keyboard-interaction.md


6. Common Mistakes

6.1 Headings Inside <summary>

<!-- WRONG — heading semantics destroyed -->
<details>
  <summary><h3>FAQ Item</h3></summary>
  <p>Answer</p>
</details>

<!-- RIGHT (native) — no heading in summary -->
<details>
  <summary>FAQ Item</summary>
  <p>Answer</p>
</details>

<!-- RIGHT (ARIA) — heading wraps button -->
<h3><button aria-expanded="false" aria-controls="p1">FAQ Item</button></h3>
<div id="p1" role="region" aria-labelledby="..." hidden>Answer</div>

Headings inside <summary> are flattened to presentational role. Users cannot navigate to them via heading shortcuts. (Roselli 2019; O'Hara 2018)

6.2 Links as Disclosure Triggers

<!-- WRONG — link sets navigation expectation -->
<a href="#" onclick="toggle()">Show details</a>

<!-- RIGHT -->
<button aria-expanded="false" aria-controls="details-1">Show details</button>

Disclosure triggers must be buttons. Links signal navigation, not toggle. (Roselli 2020)

6.3 Adjacent <details> Called "Accordion" Without Grouping

<!-- WRONG — no group semantics -->
<details><summary>Q1</summary><p>A1</p></details>
<details><summary>Q2</summary><p>A2</p></details>

<!-- RIGHT — wrap in labeled group -->
<div role="group" aria-labelledby="faq-heading">
  <h2 id="faq-heading">FAQ</h2>
  <details name="faq"><summary>Q1</summary><p>A1</p></details>
  <details name="faq"><summary>Q2</summary><p>A2</p></details>
</div>

Adjacent <details> lack group semantics. Wrap in a container with role="group" and aria-labelledby. (Roselli 2023)

6.4 Adding role="button" to <summary>

<!-- WRONG — suppresses state announcements in VoiceOver -->
<details>
  <summary role="button">Toggle</summary>
  <p>Content</p>
</details>

<!-- RIGHT — summary already has implicit button behavior -->
<details>
  <summary>Toggle</summary>
  <p>Content</p>
</details>

Native <summary> already has button-like behavior. Adding role="button" can suppress expanded/collapsed state in VoiceOver/Safari. (O'Hara 2018)

6.5 role="region" on All Panels in Large Accordions

<!-- WRONG with 6+ sections — landmark proliferation -->
<div role="region" aria-labelledby="h1">...</div>
<div role="region" aria-labelledby="h2">...</div>
<!-- ... 8 more regions ... -->

<!-- RIGHT — omit role="region" for large accordions -->
<div id="panel-1" aria-labelledby="btn-1" hidden>...</div>

Too many landmarks makes landmark navigation useless. APG recommends avoiding role="region" when there are 6 or more panels. (APG Accordion Pattern)

6.6 Hidden Content Still in Accessibility Tree

<!-- WRONG — visually hidden but still announced -->
<div class="panel" style="position: absolute; left: -9999px">Content</div>

<!-- RIGHT — properly hidden -->
<div class="panel" hidden>Content</div>
<!-- or -->
<div class="panel" style="display: none">Content</div>

If content is meant to be hidden, hide it from everyone. Off-screen positioning leaves content in the accessibility tree. (O'Hara 2017)

Full list: ${CLAUDE_SKILL_DIR}/references/common-mistakes.md


7. Cross-References

  • aria-decision-framework — check whether you need ARIA at all (use native HTML first)
  • ${CLAUDE_SKILL_DIR}/references/native-details-summary.md — full native element guide
  • ${CLAUDE_SKILL_DIR}/references/keyboard-interaction.md — complete keyboard spec
  • ${CLAUDE_SKILL_DIR}/references/screen-reader-behavior.md — per-AT behavior differences
  • ${CLAUDE_SKILL_DIR}/references/common-mistakes.md — expanded anti-patterns with citations
  • ${CLAUDE_SKILL_DIR}/references/sources.yaml — provenance for all cited sources

What ships with it: 5 files

20.0 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.