
Exclusive Accordions without Scripts using HTML details and name
For more than a decade, web developers seeking to build exclusive accordions—where expanding one disclosure section automatically collapses all sibling panels—were forced to write custom JavaScript. Standard implementations required attaching event listeners to each <details> element, intercepting the toggle event, iterating across adjacent elements, and manually removing the open attribute. This recurring script overhead introduced potential timing bugs, state synchronization headaches, and unnecessary bundle payload for an interface pattern found across nearly every corporate FAQ and product documentation portal.
The HTML living standard resolved this architectural gap by adding support for the name attribute on the <details> element. Functioning analogously to radio button groupings with <input type="radio" name="...">, assigning identical name values across multiple <details> elements instructs the browser engine to enforce mutual exclusion natively. Because the state changes execute at the parser and rendering engine level, keyboard navigation, focus management, and screen reader accessibility remain completely intact without a single line of client-side scripting.
Example
<!-- Mutually exclusive FAQ accordion grouped by the name attribute -->
<div class="accordion-group">
<details name="faq-group" open>
<summary>What payment methods do you accept?</summary>
<p>We support all major credit cards, PayPal, wire transfers, and localized payment gateways.</p>
</details>
<details name="faq-group">
<summary>Can I upgrade or downgrade my subscription anytime?</summary>
<p>Yes. Plan adjustments take effect immediately, and billing balances are prorated automatically.</p>
</details>
<details name="faq-group">
<summary>Do you offer a self-hosted enterprise deployment?</summary>
<p>Our enterprise tier includes air-gapped Docker containers, Kubernetes Helm charts, and custom SSO.</p>
</details>
</div>
Implementation
<!-- Progressive, accessible, and smoothly styled exclusive accordion -->
<section class="faq-container" aria-labelledby="faq-title">
<h2 id="faq-title">Frequently Asked Questions</h2>
<div class="accordion">
<details name="billing-faq" class="accordion-item" open>
<summary class="accordion-trigger">
<span class="trigger-text">How does the 14-day free trial work?</span>
<span class="trigger-icon" aria-hidden="true"></span>
</summary>
<div class="accordion-body">
<p>
You receive complete access to all enterprise features during the trial window.
No credit card is required to register, and you can cancel anytime with zero commitments.
</p>
</div>
</details>
<details name="billing-faq" class="accordion-item">
<summary class="accordion-trigger">
<span class="trigger-text">What happens when my team reaches its user limit?</span>
<span class="trigger-icon" aria-hidden="true"></span>
</summary>
<div class="accordion-body">
<p>
Account administrators receive an automated email alert when usage reaches 90% capacity.
Additional seats can be provisioned instantly from the organization settings dashboard.
</p>
</div>
</details>
<details name="billing-faq" class="accordion-item">
<summary class="accordion-trigger">
<span class="trigger-text">Are discounts available for educational institutions?</span>
<span class="trigger-icon" aria-hidden="true"></span>
</summary>
<div class="accordion-body">
<p>
Qualified non-profit institutions and accredited educational entities receive a 40% discount
on all annual plans upon presenting valid accreditation documentation.
</p>
</div>
</details>
</div>
</section>
<style>
/* Modern styling for native exclusive accordions */
.accordion {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-width: 48rem;
margin: 1.5rem 0;
}
.accordion-item {
border: 1px solid var(--border-color, #e2e8f0);
border-radius: 8px;
background-color: var(--surface-1, #ffffff);
overflow: hidden;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.accordion-item[open] {
border-color: var(--accent-color, #2563eb);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.accordion-trigger {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.25rem;
font-weight: 600;
color: var(--text-heading, #0f172a);
cursor: pointer;
list-style: none; /* Hide default browser disclosure triangle */
user-select: none;
}
/* Remove default marker in WebKit and Blink */
.accordion-trigger::-webkit-details-marker {
display: none;
}
.accordion-trigger:focus-visible {
outline: 2px solid var(--accent-color, #2563eb);
outline-offset: -2px;
}
/* Custom animated chevron indicator */
.trigger-icon {
width: 10px;
height: 10px;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: rotate(45deg);
transition: transform 0.25s ease;
margin-left: 1rem;
flex-shrink: 0;
}
.accordion-item[open] .trigger-icon {
transform: rotate(-135deg);
}
/* Target content wrapper or modern ::details-content pseudo-element */
.accordion-body {
padding: 0 1.25rem 1.25rem 1.25rem;
color: var(--text-body, #475569);
line-height: 1.6;
}
/* Progressive enhancement with ::details-content where supported */
@supports selector(::details-content) {
.accordion-item::details-content {
transition: opacity 0.2s ease, content-visibility 0.2s allow-discrete;
opacity: 0;
}
.accordion-item[open]::details-content {
opacity: 1;
}
}
</style>
<script>
// Progressive enhancement fallback for legacy browser engines
// Ensures mutual exclusion even if the browser does not yet support the HTML name attribute
if (!('name' in HTMLDetailsElement.prototype)) {
document.querySelectorAll('details[name]').forEach(details => {
details.addEventListener('toggle', event => {
if (details.open) {
const groupName = details.getAttribute('name');
document.querySelectorAll(`details[name="${groupName}"][open]`).forEach(sibling => {
if (sibling !== details) {
sibling.removeAttribute('open');
}
});
}
});
});
}
</script>
Main Point: The HTML details element with the name attribute provides native mutual exclusion for accordions, delivering bulletproof accessibility and zero-script behavior with graceful progressive enhancement.
Credits
Photo by Scott Webb on Unsplash