<u-details>
There is no longer need for <u-details> 🎉
Please use native <details> as it has sufficient support
in major browsers and screen readers, but import @u-elements/u-details/polyfill to support Android Firefox users with Talkback screen reader.
<details> lets you open and close content when clicking on a child <summary>.
You can use it to make things like accordions, expandables, FAQs, dropdowns, etc.
Quick intro:
- Use
<summary>as a direct child - this is the label - Use any other content in
<details>- this will hide/show - Use the
openattribute on<details>to change state - MDN Web Docs: <details> (HTMLDetailsElement) / <summary> (HTMLElement)
Example
<details> <summary>Details</summary> Something small enough to escape casual notice. </details>
Install polyfill
npm add -S @u-elements/u-detailspnpm add -S @u-elements/u-detailsyarn add @u-elements/u-detailsbun add -S @u-elements/u-details<script type="module" src="https://unpkg.com/@u-elements/u-details@latest/dist/polyfill.js"></script>import '@u-elements/u-details/polyfill';Attributes and props
<details>
- Attributes: all global HTML attributes such as
id,class,data-openshows content if attribute is present. By default this attribute is absent which means the content is hidden. Note: Settingopen="false"will not work as intended, asopenis a boolean attribute you should provide or remove entirely.nameenables multiple<details>elements to be connected, with only one open at a time.
- DOM interface:
HTMLDetailsElementHTMLDetailsElement.openreturnstrueoffalsereflecting the stateHTMLDetailsElement.namereturns the correspondingnameattribute
<summary>
- Attributes: all global HTML attributes such as
id,class,data- - DOM interface:
HTMLElement
Events
In addition to the usual events supported by HTML elements, the <details> element dispatches a toggle event after the open state is changed:
details.addEventListener('toggle', (event) => {
if (details.open) {
// the element was toggled open
} else {
// the element was toggled closed
}
});Styling and animating
The <summary> element is styled with display: list-item, but you can hide the triangle with list-style:none.
<details> hides its content - the ::details-content pseudo element.
If your browser supports interpolate-size, you can animate open/close with pure css:
<details class="animate">
<summary>Details animating if supported</summary>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent interdum diam quis eros sollicitudin, et scelerisque arcu malesuada. Nunc pellentesque eleifend nulla a convallis.
</details>
<style>
.animate{
@media (prefers-reduced-motion: no-preference) {
interpolate-size: allow-keywords;
}
&::details-content {
block-size: 0;
overflow-y: clip;
transition: content-visibility 500ms allow-discrete,
height 500ms;
}
&[open]::details-content {
height: auto;
}
}
</style>
Find-in-page
Even when a <details> element is closed, all of its content remains discoverable through the find-in-page search feature (e.g., Ctrl or Command + F keys). This behavior is supported by various browsers. If a user conducts a search for content within a details element, it will automatically open and trigger the toggle event.
Accessibility (tested 21.01.26)
| Screen reader | <details> | @u-elements/u-details/polyfill |
|---|---|---|
| VoiceOver (Mac) + Chrome | ✅ | ✅ |
| VoiceOver (Mac) + Edge | ✅ | ✅ |
| VoiceOver (Mac) + Firefox | ✅ | ✅ |
| VoiceOver (Mac) + Safari | ✅ | ✅ |
| VoiceOver (iOS) + Chrome | ✅ | ✅ |
| VoiceOver (iOS) + Safari | ✅ | ✅ |
| Jaws (PC) + Chrome | ✅ | ✅ |
| Jaws (PC) + Edge | ✅ | ✅ |
| Jaws (PC) + Firefox | ✅ | ✅ |
| NVDA (PC) + Chrome | ✅ | ✅ |
| NVDA (PC) + Edge | ✅ | ✅ |
| NVDA (PC) + Firefox | ✅ | ✅ |
| Narrator (PC) + Chrome | ✅ | ✅ |
| Narrator (PC) + Edge | ✅ | ✅ |
| Narrator (PC) + Firefox | ✅ | ✅ |
| TalkBack (Android) + Chrome | ✅ | ✅ |
| TalkBack (Android) + Samsung Internet | ✅ | |
| TalkBack (Android) + Firefox | ❌ Does not announce role or state | ✅ |
Specifications
- DOM interface: HTMLDetailsElement
- HTML Standard: The <details> element
- HTML Standard: The <summary> element
Changelog
- 0.2.2: Correct package name in deprecation message
- 0.2.1: Ensures single polyfill instance in hot-reloaded environments
- 0.2.0: Deprecateds
<u-details>and adds@u-elements/u-details/polyfill - 0.1.5: Add
tabindex="-1"to content when closed to preved Firefox from making it a tabstop - 0.1.4: Remove
aria-labelledby="summary-id"to reduce information duplication - 0.1.3: Enable declarative shadow root support and export
UHTMLDetailsShadowRootfor easier server side rendering - 0.1.2: Add
role="group"to align with semantics