The collapsible component provides a clean solution for managing large, secondary content or detailed information that might otherwise clutter the interface. When implemented correctly, it allows users to progressively discover content based on their interest level, maintaining a clean, focused interface by default.
This pattern is particularly useful for:
- FAQ sections
- Detailed specifications
- Supplementary information
- Long descriptions that would disrupt the main content flow
Native HTML Solution
Basic HTML5 provides built-in <details>
and <summary>
elements for collapsible content that require no JavaScript and work across all modern browsers:
Native HTML Example
HTML5 provides built-in elements for collapsible content that require no JavaScript and work across all modern browsers:
<details>
<summary>Click to expand</summary>
<p>This content is hidden by default and appears when the user clicks the summary.</p>
</details>
Using pure HTML elements offer several advantages:
- Zero JavaScript dependency
- Built-in accessibility features
- Native browser support
- Consistent behavior across platforms
JavaScript
For cases requiring more complex behavior or specific design patterns that go beyond what native HTML elements provide, a custom JavaScript implementation is available:
Implementation Example
The script handles two common HTML structures:
- Structure 1: Trigger and content are siblings
- Structure 2: Trigger inside parent element (like
<p>
) followed by content
Below is a practical implementation example showing how the collapsible component works.
// Structure 1 (siblings under same parent):
<div class="container">
<div class="collapsible-trigger">Trigger<span> class="collapsible-icon material-icons-outlined">keyboard_arrow_down</span></div>
<div class="collapsible-content">Content goes here</div>
</div>
// Structure 2 (content after trigger's parent):
<div class="container">
<p>
<span class="collapsible-trigger">Trigger<span class="collapsible-icon">...>/span></span>
</p>
<div class="collapsible-content">Content</div>
</div>
Note: The .collapsible-icon
element is optional. If it's not present, the script will still toggle the visibility of the content, but there won't be any icon changes.
Technical Requirements
Pay attention for several points:
- The clickable element must have class
.collapsible-trigger
- The hidden content must have class
.collapsible-content
- Optional: Icon element with class
.collapsible-icon
- The default state of
.collapsible-content
should be set asdisplay: none;
ormax-height: 0;
to ensure content is hidden before JavaScript runs
Raw code
document.addEventListener('DOMContentLoaded', function() {
// Find all trigger elements
const triggers = document.querySelectorAll('.collapsible-trigger');
// Add click handler to each trigger
triggers.forEach(trigger => {
trigger.addEventListener('click', function() {
// Try to find related content element
let content;
// Check if trigger and content are siblings
if (this.nextElementSibling && this.nextElementSibling.classList.contains('collapsible-content')) {
content = this.nextElementSibling;
}
// Check if content is the next sibling of trigger's parent
else if (this.parentElement &&
this.parentElement.nextElementSibling &&
this.parentElement.nextElementSibling.classList.contains('collapsible-content')) {
content = this.parentElement.nextElementSibling;
}
// Exit if no content found
if (!content) return;
// Find the icon (if it exists)
const icon = this.querySelector('.collapsible-icon');
// Check if content is currently visible
const isVisible = window.getComputedStyle(content).display !== 'none';
// Toggle visibility
if (isVisible) {
content.style.display = 'none';
if (icon) icon.textContent = 'keyboard_arrow_down';
} else {
content.style.display = 'block';
if (icon) icon.textContent = 'keyboard_arrow_up';
}
});
});
});
Pseudo-Link Styling Cheat Sheet
Create a special style for pseudo-links.
Following best practices, .collapsible-trigger
elements should be visually distinguished to indicate their interactive nature.
When designing the visual treatment for collapsible triggers, aim for a balance between subtlety and clarity. Users should recognize them as interactive elements without disrupting the flow of content.
Bonus: If it’s part of a bigger text block, avoid display: block
— it should feel natural inside the flow.