Bootstrap 5 Accordion JS (Collapse + data-bs-parent + 41 KB infra) vs Native <details name=""> exclusive accordion
parent option (init cost), then opens
each item in sequence within each group for 100 cycles (5,000 switch operations per section).
Opening an item auto-closes its siblings. DOM mutations are counted via MutationObserver.
CSS transitions are disabled during the run so we measure raw JS overhead, not animation time.
Uses bootstrap.Collapse with data-bs-parent — manages .show / .collapsing classes, reads scrollHeight, fires lifecycle events, auto-closes siblings via parent traversal. Requires 8 JS dependency files (41 KB).
Uses <details name=""> — only one open at a time per group, browser closes siblings automatically. Built-in keyboard support (Enter/Space). Zero initialization, zero framework JS.
| Metric | Bootstrap Accordion | Native <details name> |
|---|---|---|
| Initialization time (10 groups × 5 items) | - | - |
| Switch time (100 cycles × 10 groups × 5 items) | - | - |
| DOM mutations (100 cycles × 10 groups × 5 items) | - | - |
| Instance memory cost (50 accordion items) | - | - |
|
JS code size
collapse.js (8.6 KB) +
base-component (2.8 KB) +
event-handler (9.2 KB) +
selector-engine (4.1 KB) +
data (2.1 KB) +
manipulator (2.3 KB) +
util (9.1 KB) +
config (2.5 KB)
|
- | - |
|
CSS output size
_accordion.scss (4.9 KB)
|
- | - |
Collapse + data-bs-parent
<details name="">
Collapse component with a
data-bs-parent attribute that triggers exclusive behavior. Under the hood, when one item
opens, Bootstrap's JS traverses the parent container, queries all sibling .collapse.show
elements, and programmatically calls .hide() on each — reading scrollHeight,
setting inline style.height, swapping .collapsing classes, and firing
4 lifecycle events (show/shown/hide/hidden) per item.
This requires 41 KB of JavaScript infrastructure (custom event system, data store, config parser,
DOM manipulation utils). Native <details name=""> provides the identical exclusive
accordion behavior with zero initialization and zero JavaScript —
the browser closes sibling details elements automatically when one opens.
Click items below to compare the animation feel. Both have a 0.35s ease transition. The native side uses only CSS.
.collapsing + scrollHeight)
scrollHeight, sets inline style.height, adds the .collapsing class, fires 4 events, then swaps to .collapse.show. The sibling is programmatically closed with the same process.scrollHeight reads, 2 × inline style mutations, multiple class changes, and 8 lifecycle events total (4 for hide + 4 for show).::details-content)
::details-content pseudo-element transitions block-size from 0 to auto. The browser automatically closes the sibling when this opens. Zero JavaScript.scrollHeight reads, no forced reflows, no class toggling, no inline styles, no lifecycle events. The browser’s CSS engine handles everything.name="") for exclusivity.<!-- Exclusive accordion — only one open at a time -->
<details name="my-accordion" open>
<summary>First item</summary>
<p>First panel content.</p>
</details>
<details name="my-accordion">
<summary>Second item</summary>
<p>Second panel content.</p>
</details>
<details name="my-accordion">
<summary>Third item</summary>
<p>Third panel content.</p>
</details>
<!-- That's it. No JS. No ARIA attributes.
Browser handles exclusivity, keyboard, animation
(via ::details-content), and semantics. -->
details {
interpolate-size: allow-keywords;
}
details::details-content {
transition: block-size 0.35s ease,
content-visibility 0.35s ease allow-discrete;
block-size: 0;
overflow: hidden;
}
details[open]::details-content {
block-size: auto;
}