HyAccordion
An accordion component using CSS Grid animation for smooth expand/collapse transitions.
CSS Grid Animation Approach
This implementation uses CSS Grid's grid-template-rows property to create smooth expand/collapse animations:
- Collapsed State:
grid-template-rows: 0fr(zero height) - Expanded State:
grid-template-rows: 1fr(content height) - Browser Handled: Height calculations are managed by the browser
- Content Adaptive: Automatically adjusts when content changes
- Clean Implementation: No JavaScript height measurements required
Technical Benefits
- Eliminates need for ResizeObserver height tracking
- No manual animation frame management
- Automatic content size adaptation
- Smooth CSS transitions
- Reduced code complexity
Accessibility Features
- Full keyboard navigation (Enter/Space to toggle, Tab to focus)
- ARIA live regions for screen reader announcements
- Proper ARIA attributes and relationships
- High contrast mode support
- Reduced motion support with instant transitions
- Visible focus indicators
Browser Compatibility
CSS Grid animation is supported in:
- Chrome 57+ (March 2017)
- Firefox 52+ (March 2017)
- Safari 10.1+ (March 2017)
- Edge 16+ (October 2017)
Examples
Basic Usage
<hy-accordion title="Settings" expanded>
<p>Configure your application settings here.</p>
</hy-accordion>Flat / borderless presentation (emphasis="plain")
<hy-accordion emphasis="plain" title="Neutral">
<p>
Chromeless header — no box, no border, no radius. Add a `border-block-end` rule consumer-side
for a section divider.
</p>
</hy-accordion>With All Features
<hy-accordion
title="Email Settings"
subtitle="Configure notifications and preferences"
optional-text="Last updated today"
prefix-icon-name="mail"
size="medium"
announce-state-changes="true"
animation-duration="400"
>
<div>
<h3>Notification Settings</h3>
<p>Choose how you want to receive notifications.</p>
</div>
</hy-accordion>Custom Header with Slots
<hy-accordion size="large">
<div slot="header">
<strong>Project Status</strong>
<small style="color: green; margin-left: 0.5em;">âœ" Complete</small>
</div>
<hy-icon slot="expand-icon" name="keyboard-arrow-down"></hy-icon>
<p>Project details and completion information.</p>
</hy-accordion>Programmatic Control
<hy-accordion id="myAccordion" title="API Example">
<p>Content that can be controlled via JavaScript.</p>
</hy-accordion>
<script>
const accordion = document.getElementById('myAccordion');
// Listen for state changes
accordion.addEventListener('toggle', (e) => {
console.log('State changed:', e.detail.expanded);
});
// Programmatic control
accordion.expand(); // Expand with animation
accordion.collapse(); // Collapse with animation
accordion.toggle(); // Toggle current state
</script>Custom Animation Timing
You can customize animation via CSS custom properties:
hy-accordion {
--hy-accordion-expand-duration: 500ms;
--hy-accordion-expand-easing: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}Events
- toggle - Fired when the accordion state changes (expand or collapse). Detail:
{ expanded: boolean } - expand - Fired specifically when the accordion expands. Detail:
{ expanded: boolean } - collapse - Fired specifically when the accordion collapses. Detail:
{ expanded: boolean } - transition-end - Fired when the CSS Grid animation completes. Detail:
{ expanded: boolean }
Slots
- default - The main content displayed when the accordion is expanded
- prefix - Custom prefix content that overrides the
prefix-icon-nameproperty - header - Custom header content that overrides
title,subtitle, andoptional-textproperties - expand-icon - Custom expand/collapse indicator that overrides the
icon-nameproperty
Methods
toggle()
Toggles the accordion between expanded and collapsed states. Triggers CSS Grid animation and appropriate events.
expand()
Expands the accordion to show its content. Uses CSS Grid animation for smooth transition.
collapse()
Collapses the accordion to hide its content. Uses CSS Grid animation for smooth transition.
focus()
Sets focus on the accordion header button for keyboard navigation.
blur()
Removes focus from the accordion header button.
willUpdate()
Generates unique IDs before the first render to prevent update-after-update warnings. IDs are generated client-side only to prevent SSR/client hydration mismatches.
During SSR, crypto.randomUUID() generates different values on server vs client, causing Lit to render duplicate components when IDs are generated in constructor. By deferring ID generation until willUpdate (before first render), we ensure server and client DOM consistency while avoiding double-render warnings.
updated()
Called after the element's properties have been updated.
disconnectedCallback()
Called when element is removed from the DOM.
render()
Renders the accordion component template.