Interactive
HTML5
The <details> element creates a native disclosure widget where users can show or hide additional information. It provides built-in toggle functionality without requiring JavaScript, making it perfect for FAQs, expandable sections, and progressive disclosure patterns.
Interactive code playground requires JavaScript. Here's the code:
<details>
<summary>What is HTML?</summary>
<p>HTML (HyperText Markup Language) is the standard markup language
for creating web pages. It describes the structure of a web page
semantically and originally included cues for its appearance.</p>
</details>
<details open>
<summary>Why learn HTML?</summary>
<p>HTML is the foundation of all web development. Understanding HTML
is essential for creating websites, web applications, and working
with any web technology.</p>
</details>
< summary > Click to expand </ summary >
Hidden content goes here...
Attribute Value Description openBoolean When present, the details are visible (expanded)
The <details> element supports all global attributes .
The open attribute controls the initial state of the disclosure widget:
Interactive code playground requires JavaScript. Here's the code:
<!-- Collapsed by default -->
<details>
<summary>Closed Initially</summary>
<p>This content is hidden until clicked.</p>
</details>
<!-- Expanded by default -->
<details open>
<summary>Open Initially</summary>
<p>This content is visible immediately.</p>
</details>
<!-- Can be toggled with JavaScript -->
<details id="jsControl">
<summary>Controlled by JavaScript</summary>
<p>This can be opened and closed programmatically.</p>
</details>
<button onclick="toggleDetails()">Toggle Details</button>
<script>
function toggleDetails() {
const details = document.getElementById('jsControl');
details.open = !details.open;
}
</script>
Interactive code playground requires JavaScript. Here's the code:
<h2>Frequently Asked Questions</h2>
<details>
<summary>How do I reset my password?</summary>
<p>Click on "Forgot Password" on the login page, enter your email
address, and we'll send you a password reset link.</p>
</details>
<details>
<summary>What payment methods do you accept?</summary>
<p>We accept all major credit cards (Visa, MasterCard, American
Express), PayPal, and bank transfers for enterprise customers.</p>
</details>
<details>
<summary>Can I cancel my subscription anytime?</summary>
<p>Yes! You can cancel your subscription at any time from your
account settings. No questions asked.</p>
</details>
<style>
details {
margin: 1em 0;
padding: 1em;
border: 1px solid #ddd;
border-radius: 4px;
}
details[open] {
background: #f9fafb;
}
summary {
cursor: pointer;
font-weight: bold;
user-select: none;
}
summary:hover {
color: #3b82f6;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<details>
<summary>Chapter 1: Introduction</summary>
<p>Introduction to the topic...</p>
<details>
<summary>Section 1.1: Background</summary>
<p>Historical context and background information...</p>
</details>
<details>
<summary>Section 1.2: Methodology</summary>
<p>Research methods and approaches used...</p>
</details>
</details>
<details>
<summary>Chapter 2: Analysis</summary>
<p>Detailed analysis and findings...</p>
</details>
<style>
details {
margin: 0.5em 0;
padding: 0.5em;
border-left: 3px solid #3b82f6;
}
details details {
margin-left: 1em;
border-left-color: #8b5cf6;
}
summary {
cursor: pointer;
font-weight: 600;
padding: 0.5em;
}
summary:hover {
background: #f3f4f6;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<article>
<h2>Movie Review: The Sixth Sense (1999)</h2>
<p>This psychological thriller directed by M. Night Shyamalan
is a masterpiece of suspense and storytelling...</p>
<details>
<summary>⚠️ Spoiler Warning - Click to Reveal</summary>
<p style="background: #fef3c7; padding: 1em; margin-top: 1em;">
<strong>Major Plot Twist:</strong> Bruce Willis's character
has been dead the entire movie. The "people" he sees are
actually ghosts, and he himself is one of them.
</p>
</details>
</article>
<style>
details {
margin: 1.5em 0;
padding: 1em;
border: 2px solid #f59e0b;
border-radius: 8px;
background: #fffbeb;
}
summary {
cursor: pointer;
font-weight: bold;
color: #b45309;
user-select: none;
}
summary:hover {
color: #f59e0b;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<h3>Array Methods</h3>
<details>
<summary><code>map()</code> - Transform array elements</summary>
<pre style="background: #1e293b; color: #e2e8f0; padding: 1em;
border-radius: 4px; overflow-x: auto;">
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]</pre>
<p>Creates a new array with the results of calling a function
on every element.</p>
</details>
<details>
<summary><code>filter()</code> - Filter array elements</summary>
<pre style="background: #1e293b; color: #e2e8f0; padding: 1em;
border-radius: 4px; overflow-x: auto;">
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(n => n % 2 === 0);
// [2, 4]</pre>
<p>Creates a new array with elements that pass a test function.</p>
</details>
<style>
details {
margin: 1em 0;
border-bottom: 1px solid #e5e7eb;
}
summary {
cursor: pointer;
padding: 0.75em 0;
font-family: 'Courier New', monospace;
}
summary:hover {
color: #3b82f6;
}
details[open] summary {
margin-bottom: 0.5em;
}
</style>
The disclosure marker (triangle/arrow) can be styled or hidden:
Interactive code playground requires JavaScript. Here's the code:
<details class="custom-marker">
<summary>Custom disclosure marker</summary>
<p>The triangle has been replaced with custom content.</p>
</details>
<style>
.custom-marker summary {
list-style: none;
cursor: pointer;
padding: 1em;
background: #3b82f6;
color: white;
border-radius: 4px;
}
.custom-marker summary::-webkit-details-marker {
display: none;
}
.custom-marker summary::before {
content: '▶ ';
display: inline-block;
transition: transform 0.2s;
}
.custom-marker[open] summary::before {
transform: rotate(90deg);
}
.custom-marker summary:hover {
background: #2563eb;
}
</style> Interactive code playground requires JavaScript. Here's the code:
<details class="animated-icon">
<summary>Click to expand</summary>
<p>Content with a smooth animated icon.</p>
</details>
<style>
.animated-icon summary {
list-style: none;
cursor: pointer;
padding: 1em;
border: 2px solid #8b5cf6;
border-radius: 4px;
display: flex;
align-items: center;
gap: 0.5em;
}
.animated-icon summary::-webkit-details-marker {
display: none;
}
.animated-icon summary::before {
content: '+';
font-size: 1.5em;
font-weight: bold;
color: #8b5cf6;
transition: transform 0.3s ease;
}
.animated-icon[open] summary::before {
transform: rotate(45deg);
}
.animated-icon[open] {
background: #f5f3ff;
}
</style> Interactive code playground requires JavaScript. Here's the code:
<details class="svg-icon">
<summary>
<svg width="16" height="16" viewBox="0 0 16 16"
class="chevron" aria-hidden="true">
<path d="M4 6l4 4 4-4" stroke="currentColor"
stroke-width="2" fill="none" stroke-linecap="round"/>
</svg>
Expandable content
</summary>
<p>Content with SVG chevron icon.</p>
</details>
<style>
.svg-icon summary {
list-style: none;
cursor: pointer;
padding: 1em;
display: flex;
align-items: center;
gap: 0.5em;
background: #f3f4f6;
border-radius: 4px;
}
.svg-icon summary::-webkit-details-marker {
display: none;
}
.chevron {
transition: transform 0.2s ease;
}
.svg-icon[open] .chevron {
transform: rotate(180deg);
}
.svg-icon summary:hover {
background: #e5e7eb;
}
</style>
The <details> element fires a toggle event when opened or closed:
Interactive code playground requires JavaScript. Here's the code:
<details id="trackedDetails">
<summary>Track open/close events</summary>
<p>This details element is being monitored.</p>
</details>
<div id="eventLog" style="margin-top: 1em; padding: 1em;
background: #f3f4f6; border-radius: 4px; min-height: 60px;">
<strong>Event Log:</strong>
<div id="log"></div>
</div>
<script>
const details = document.getElementById('trackedDetails');
const log = document.getElementById('log');
details.addEventListener('toggle', (event) => {
const timestamp = new Date().toLocaleTimeString();
const state = details.open ? 'OPENED' : 'CLOSED';
const entry = document.createElement('div');
entry.textContent = timestamp + ' - Details ' + state;
entry.style.color = details.open ? '#059669' : '#dc2626';
log.prepend(entry);
});
</script>
Create an accordion where only one item is open at a time:
Interactive code playground requires JavaScript. Here's the code:
<div class="accordion">
<details>
<summary>First Item</summary>
<p>Content for the first item.</p>
</details>
<details>
<summary>Second Item</summary>
<p>Content for the second item.</p>
</details>
<details>
<summary>Third Item</summary>
<p>Content for the third item.</p>
</details>
</div>
<script>
const accordion = document.querySelector('.accordion');
const details = accordion.querySelectorAll('details');
details.forEach(targetDetail => {
targetDetail.addEventListener('toggle', () => {
if (targetDetail.open) {
details.forEach(detail => {
if (detail !== targetDetail) {
detail.open = false;
}
});
}
});
});
</script>
<style>
.accordion details {
margin: 0.5em 0;
padding: 1em;
border: 1px solid #e5e7eb;
border-radius: 4px;
}
.accordion summary {
cursor: pointer;
font-weight: 600;
}
.accordion details[open] {
background: #f9fafb;
border-color: #3b82f6;
}
</style>
Add smooth animations to the details element:
Interactive code playground requires JavaScript. Here's the code:
<details class="animated-details">
<summary>Smooth Animation</summary>
<div class="content">
<p>This content slides in smoothly when opened.</p>
<p>Animations make the experience more polished.</p>
</div>
</details>
<style>
.animated-details {
margin: 1em 0;
border: 2px solid #3b82f6;
border-radius: 8px;
overflow: hidden;
}
.animated-details summary {
cursor: pointer;
padding: 1em;
background: #3b82f6;
color: white;
font-weight: bold;
user-select: none;
list-style: none;
}
.animated-details summary::-webkit-details-marker {
display: none;
}
.animated-details summary:hover {
background: #2563eb;
}
.animated-details .content {
padding: 1em;
animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
</style>
The <details> element has excellent built-in accessibility:
Enter/Space : Toggle open/closed when summary is focused
Tab : Move focus to next interactive element
Interactive code playground requires JavaScript. Here's the code:
<details>
<summary>
<span aria-label="Show more information about pricing">
Pricing Details
</span>
</summary>
<div role="region" aria-label="Pricing information">
<p>Our pricing starts at $10/month for individuals.</p>
<p>Enterprise plans are available starting at $100/month.</p>
</div>
</details>
<style>
details {
margin: 1em 0;
padding: 1em;
border: 1px solid #ddd;
border-radius: 4px;
}
summary {
cursor: pointer;
font-weight: bold;
}
summary:focus {
outline: 2px solid #3b82f6;
outline-offset: 2px;
}
</style>
Descriptive summaries : Make summary text clear and actionable
Keyboard accessible : Ensure all functionality works with keyboard
Focus indicators : Provide clear focus styles
ARIA labels : Add additional context when needed
Logical structure : Use proper heading hierarchy inside details
Interactive code playground requires JavaScript. Here's the code:
<div class="settings-panel">
<h2>Settings</h2>
<details open>
<summary>Account Settings</summary>
<label>
Email Notifications
<input type="checkbox" checked>
</label>
<label>
Two-Factor Authentication
<input type="checkbox">
</label>
</details>
<details>
<summary>Privacy Settings</summary>
<label>
Profile Visibility
<select>
<option>Public</option>
<option>Friends Only</option>
<option>Private</option>
</select>
</label>
</details>
<details>
<summary>Notification Preferences</summary>
<label>
Email Updates
<input type="checkbox" checked>
</label>
<label>
SMS Alerts
<input type="checkbox">
</label>
</details>
</div>
<style>
.settings-panel {
max-width: 400px;
padding: 1em;
background: #f9fafb;
border-radius: 8px;
}
.settings-panel details {
margin: 0.5em 0;
padding: 0.75em;
background: white;
border-radius: 4px;
}
.settings-panel summary {
cursor: pointer;
font-weight: 600;
color: #1f2937;
}
.settings-panel label {
display: block;
margin: 0.75em 0;
cursor: pointer;
}
.settings-panel input,
.settings-panel select {
margin-left: 0.5em;
}
</style>
Interactive code playground requires JavaScript. Here's the code:
<nav class="mobile-nav">
<details>
<summary>☰ Menu</summary>
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li>
<details>
<summary>Services</summary>
<ul>
<li><a href="#web">Web Design</a></li>
<li><a href="#seo">SEO</a></li>
<li><a href="#marketing">Marketing</a></li>
</ul>
</details>
</li>
<li><a href="#contact">Contact</a></li>
</ul>
</details>
</nav>
<style>
.mobile-nav {
background: #1f2937;
color: white;
}
.mobile-nav summary {
cursor: pointer;
padding: 1em;
font-size: 1.2em;
font-weight: bold;
list-style: none;
user-select: none;
}
.mobile-nav summary::-webkit-details-marker {
display: none;
}
.mobile-nav ul {
list-style: none;
margin: 0;
padding: 0;
}
.mobile-nav a {
display: block;
padding: 0.75em 1.5em;
color: white;
text-decoration: none;
border-top: 1px solid #374151;
}
.mobile-nav a:hover {
background: #374151;
}
.mobile-nav details details summary {
padding-left: 2em;
background: #111827;
}
.mobile-nav details details a {
padding-left: 3em;
background: #0f172a;
}
</style>
Excellent Support
The <details> element is supported in all modern browsers:
Chrome : 12+ (2011)
Firefox : 49+ (2016)
Safari : 6+ (2012)
Edge : 79+ (2020)
Opera : 15+ (2013)
Mobile : Widely supported
Fallback : For older browsers, content inside <details> will be visible by default. Consider using a polyfill or JavaScript solution for critical functionality.
Always include <summary> : Required for proper functionality
Make summaries descriptive : Users should know what they’ll reveal
Don’t nest too deeply : Keep hierarchy simple and navigable
Consider mobile users : Ensure touch targets are large enough
Test keyboard navigation : All functionality must work without mouse
Provide context : Use ARIA labels when summary text isn’t enough
Style focus states : Make keyboard navigation clear
Avoid overuse : Too many collapsed sections can be overwhelming
Learn More: