<u-details>
<u-details>
lets you open and close content when clicking on a child <u-summary>
.
You can use it to make things like accordions, expandables, FAQs, dropdowns, etc.
Quick intro:
- Use
<u-summary>
as a direct child - this is the label - Use any other content in
<u-details>
- this will hide/show - Use the
open
attribute on<u-details>
to change state - MDN Web Docs: <details> (HTMLDetailsElement) / <summary> (HTMLElement)
Example
<u-details> <u-summary>Details</u-summary> Something small enough to escape casual notice. </u-details>
Install
npm add -S @u-elements/u-details
pnpm add -S @u-elements/u-details
yarn add -S @u-elements/u-details
bun add -S @u-elements/u-details
<script type="module" src="https://unpkg.com/@u-elements/u-details@latest/dist/u-details.js"></script>
Attributes and props
<u-details>
- Attributes: all global HTML attributes such as
id
,class
,data-
open
shows 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, asopen
is a boolean attribute you should provide or remove entirely.
- DOM interface:
HTMLDetailsElement
HTMLDetailsElement.open
returnstrue
offalse
reflecting the state
<u-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 <u-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
<summary>
/<u-summary>
is rendered with display: list-item
to display the open/close triangle, which is also announced by screen readers. If you wish to remove the triangle and its announcement, you can use list-style: none
.
<details>
/<u-details>
hides its content - the ::details-content
pseudo element. Since custom pseudo selector are not
possible to replicate in custom elements, u-details
instead provide ::part(details-content)
.
If your browser supports interpolate-size
, you can animate open/close with pure css:
<u-details class="animate"> <u-summary>Details animating if supported</u-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. </u-details> <style> .animate{ @media (prefers-reduced-motion: no-preference) { interpolate-size: allow-keywords; } &::part(details-content) { block-size: 0; overflow-y: clip; transition: content-visibility 500ms allow-discrete, height 500ms; } &[open]::part(details-content) { height: auto; } } </style>
Find-in-page
Even when a <details>
/<u-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 16.09.24)
Screen reader | <details> | <u-details> |
---|---|---|
VoiceOver (Mac) + Chrome | ✅ | ✅ |
VoiceOver (Mac) + Edge | ✅ | ✅ |
VoiceOver (Mac) + Firefox | ✅ | ✅ |
VoiceOver (Mac) + Safari | ❌ Does not announce state + looses screen reader focus | ✅ |
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 | ❌ Does not announce state | ✅ |
Narrator (PC) + Edge | ✅ | ✅ |
Narrator (PC) + Firefox | ✅ | ✅ |
TalkBack (Android) + Chrome | ❌ Does not announce role | ✅ |
TalkBack (Android) + Firefox | ❌ Does not announce role or state on focus | ✅ |
TalkBack (Android) + Samsung Internet | ❌ Does not announce role | ✅ |
Specifications
- DOM interface: HTMLDetailsElement
- HTML Standard: The <details> element
- HTML Standard: The <summary> element