What Are Details and Summary Elements?
Modern web development has evolved significantly with native HTML elements that provide rich interactivity without JavaScript. The HTML <details> and <summary> elements, combined with the CSS content property, give developers powerful tools for creating disclosure widgets, accordions, and interactive content sections.
The <details> element creates a disclosure widget in which information is visible only when the widget is toggled into an open state. This native HTML element requires no JavaScript to function, making it an excellent choice for progressive enhancement. The <summary> element serves as the visible header or label for the disclosure widget.
This guide explores how to leverage these features effectively in Next.js applications, covering everything from basic implementation to advanced animation techniques and accessibility best practices.
The HTML Details Element
The <details> element creates a disclosure widget in which information is visible only when the widget is toggled into an open state. This native HTML element requires no JavaScript to function, making it an excellent choice for progressive enhancement.
Basic Implementation
The simplest implementation of <details> requires no additional elements:
<details>
Open and close the element to toggle this content.
</details>
When rendered, browsers display the word "details" as a default label. To customize this label, add a <summary> element as the first child.
The Summary Element
The <summary> element serves as the visible header or label for the disclosure widget. When users click or tap the <summary>, or press Enter when it has focus, the contents of the parent <details> toggle between visible and hidden states.
The Open Attribute
The <details> element supports an open boolean attribute that determines whether the content is visible when the page loads:
<details open>
<summary>Expanded by default</summary>
<p>This content is visible when the page loads.</p>
</details>
<details>
<summary>Collapsed by default</summary>
<p>This content is hidden until the user interacts with it.</p>
</details>
The open attribute is added and removed automatically as users interact with the control, which means it can be used in CSS to style the element differently based on its state.
Understanding the content property values and usage with pseudo-elements
String Values
Use quoted text strings to insert content before or after elements. Ideal for adding prefixes, suffixes, or decorative elements.
URL Values
Insert images directly using URL references to image files. Useful for icon sprites and decorative graphics.
Counter Values
Generate numbered content using CSS counters with increment and reset. Perfect for ordered lists with custom numbering.
Quote Values
Use open-quote and close-quote for typographic quotation marks. Creates elegant blockquote styling.
None Keyword
Completely remove pseudo-elements from rendering. Used to suppress unwanted default markers.
Normal Keyword
Computes to none for ::before and ::after pseudo-elements. Default state for non-replaced elements.
1/* String Values */2::before {3 content: "→ ";4}5 6::after {7 content: " (read more)";8}9 10/* URL Values for Images */11.icon::before {12 content: url("/images/icon-arrow.svg");13}14 15/* Counter Values */16ol {17 counter-reset: item;18}19 20li::before {21 counter-increment: item;22 content: counter(item) ". ";23}24 25/* Quote Values */26blockquote::before {27 content: open-quote;28}29 30blockquote::after {31 content: close-quote;32}Using Content with Details and Summary
The content property becomes useful when styling the <summary> marker or creating custom indicators. By combining ::marker with ::before and ::after, you can completely customize the appearance of your disclosure widgets. For a deeper dive into CSS logical properties and how they relate to content styling, see our guide on CSS logical properties.
Custom Marker Techniques
The <summary> element includes a marker (the small triangle indicator) that browsers render automatically. You can hide this marker and create entirely custom toggle icons using the CSS content property:
/* Hide the default marker */
summary::marker {
content: "";
}
/* Create a custom marker using ::before */
summary {
list-style: none;
}
summary::before {
content: "▶";
display: inline-block;
margin-right: 0.5em;
transition: transform 0.2s ease;
}
details[open] summary::before {
content: "▼";
}
This technique allows you to use any character, icon, or image as your toggle indicator while maintaining full accessibility and semantic structure.
The ::details-content Pseudo-Element
The ::details-content pseudo-element provides a way to select and apply styles to the inner content of a <details> element without affecting the <summary>. This is particularly useful for styling the expandable content area.
Browser Support
The ::details-content pseudo-element is still gaining browser support and is classified as experimental. As of early 2025, it is best to use it cautiously and provide fallback styles for older browsers:
/* Fallback using direct selection */
details[open] > :not(summary) {
background: oklch(95% 0.1812 38.35);
padding: 1rem;
}
/* Modern browsers with feature query */
@supports (selector(::details-content)) {
::details-content {
background: oklch(95% 0.1812 38.35);
padding: 1rem;
}
}
There is no need to prefix the selector with details since ::details-content is only ever valid in the context of a <details> element.
Styling the Marker with ::marker
The <summary> element includes a marker (the small triangle indicator) that browsers render automatically. The ::marker pseudo-element allows styling this marker, though with specific limitations on what properties can be changed.
Supported Properties
The ::marker pseudo-element supports:
color- Change the marker colorfont-size- Adjust marker sizecontent- Override with empty string to remove marker
summary::marker {
color: #6366f1;
font-size: 0.75em;
}
/* Remove the default marker */
summary::marker {
content: "";
}
Limitations
At the time of writing, the list-style-type property does not work consistently on summary::marker across browsers, meaning you cannot easily replace the triangle with another marker style like square or circle. Browser support varies:
- Chrome and Firefox fully support
::markeron<summary> - Safari has partial support for
::markerbut may not work consistently with<summary>
For cross-browser compatibility, the recommended approach is to hide the marker with content: "" and create a custom indicator using ::before.
Animating Details Elements
Animating <details> elements used to require JavaScript or clever CSS hacks. Modern CSS provides native solutions for smooth open/close transitions using the interpolate-size property. These techniques complement the CSS animations you use throughout your web projects.
The Challenge with Height Transitions
Animating to height: auto traditionally was not possible because CSS could not interpolate to an unknown value. This made animating <details> elements challenging without JavaScript workarounds.
Using interpolate-size
Modern browsers support the interpolate-size property, which enables transitions to keyword values like auto. Combined with the ::details-content pseudo-element, this creates smooth animations:
:root {
interpolate-size: allow-keywords;
}
::details-content {
transition: height 0.5s ease, content-visibility 0.5s ease allow-discrete;
height: 0;
overflow: clip;
}
details[open] ::details-content {
height: auto;
}
Progressive Enhancement
Always provide fallback styles for browsers that do not support interpolate-size:
@supports not (interpolate-size: allow-keywords) {
details[open] {
/* Immediate show/hide without animation */
}
}
This approach gracefully degrades to instant show/hide behavior on older browsers while providing smooth animations on supporting browsers.
Practical Examples
How do I create an FAQ section with accordions?
Use `<details name="faq">` for each question to enable accordion behavior. Each `<summary>` contains the question, and the content inside contains the answer. This creates a clean, accessible FAQ section without JavaScript.
Can I animate details elements smoothly?
Yes, using `interpolate-size: allow-keywords` and the `::details-content` pseudo-element. Combine this with CSS transitions for smooth height animations. Always provide fallback styles for browsers without support.
How do I customize the marker icon?
Set `summary::marker { content: ""; }` to hide the default marker, then use `summary::before { content: "▶"; }` with CSS transitions to create custom animated indicators.
Are details elements accessible?
Yes, `<details>` and `<summary>` have built-in accessibility. The `<summary>` receives keyboard focus and screen readers announce it as a disclosure button. Ensure content is not critical before relying solely on disclosure widgets.
Conclusion
The <details> and <summary> elements, combined with the CSS content property and modern pseudo-elements like ::details-content and ::marker, provide a powerful toolkit for creating interactive disclosure widgets. These native HTML and CSS features eliminate the need for JavaScript for common patterns like accordions and FAQs, improving performance, accessibility, and maintainability.
By leveraging these features in your Next.js applications, you can create interactive user experiences that:
- Load faster with no JavaScript dependencies for core functionality
- Work without JavaScript through progressive enhancement
- Remain accessible to users with assistive technologies
- Provide smooth animations on supporting browsers
- Scale elegantly from simple to complex implementations
Start incorporating <details> and <summary> in your projects today to build more efficient, accessible, and maintainable web interfaces.
Sources
- CSS-Tricks: Using & Styling the Details Element - Comprehensive guide covering HTML structure, marker styling, animations, and modern CSS techniques
- Web.dev: Details and Summary - Official Google documentation on HTML disclosure widgets, accessibility considerations, and semantic usage
- MDN Web Docs: content property - Complete documentation of the CSS content property values and usage
- Chrome Developer Blog: Styling Details - Modern animation techniques with interpolate-size
- CSS-Tricks: ::details-content Pseudo-Element - Technical reference for the CSS pseudo-element