Skip to content

HyAccordion

Usage examples on this page are written for Lit / plain HTML (<hy-accordion>). The same component ships as HyAccordion in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

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

html
<hy-accordion title="Settings" expanded>
  <p>Configure your application settings here.</p>
</hy-accordion>

Flat / borderless presentation (emphasis="plain")

html
<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

html
<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

html
<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

javascript
<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:

css
hy-accordion {
  --hy-accordion-expand-duration: 500ms;
  --hy-accordion-expand-easing: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

API

Properties

PropertyAttributeTypeDefaultDescription
headerIdheader-idstring''Auto-generated unique identifier for the header button element. Used to establish ARIA relationships between header and content.
contentIdcontent-idstring''Auto-generated unique identifier for the content region element. Used to establish ARIA relationships between header and content.
titletitlestring'Accordion Title'The primary title text displayed in the accordion header. Appears alongside prefix and optional text, properly aligned with the expand/collapse icon. Ignored when the header slot is used.
subtitlesubtitlestring''Secondary descriptive text displayed below the main title. Provides additional context with smaller, lighter typography. Only shown when no header slot content is provided.
optionalTextoptional-textstring''Brief supplementary text displayed after the main title. Useful for status indicators, timestamps, or brief metadata. Uses smaller, muted styling and prevents line wrapping.
sizesize'small' | 'medium' | 'large''medium'Size variant that controls typography, spacing, and visual hierarchy. - small: Compact presentation with reduced spacing - medium: Standard size for most use cases (default) - large: Prominent display with increased spacing
emphasisemphasis'solid' | 'outlined' | 'tinted' | 'plain''solid'Visual chrome weight — solid (default) / outlined / tinted / plain. - solid: surface fill + border + radius (the historic baseline — unchanged) - outlined: transparent fill, keep the border - tinted: subtle surface fill, no border - plain: chromeless (no fill, no border) — the flat / borderless presentation (industry "ghost" / "flush"); add a border-block-end rule consumer-side for a section divider.
expandedexpandedbooleanfalseWhether the accordion is currently expanded (content visible) or collapsed (content hidden). Changes trigger CSS Grid-based animations. Reflected as an attribute for CSS styling and external state queries.
disableddisabledbooleanfalseDisables all accordion interactions and applies disabled styling. When disabled, interactions are prevented and visual styling indicates disabled state.
animationDurationanimation-durationnumber300Duration in milliseconds for CSS Grid expand/collapse animations. Controls the transition speed of the grid-template-rows animation.
prefixIconNameprefix-icon-namestring | undefinedIcon name for the prefix indicator displayed before the title. Only shown when the prefix slot is not used and this property has a value.
iconNameicon-namestring'chevron-down'Icon name for the default expand/collapse indicator. The icon automatically rotates 180 degrees when the accordion expands. Ignored when the icon slot contains custom content.
announceStateChangesannounce-state-changesbooleantrueWhether to announce state changes to screen readers via ARIA live regions. Uses optimized timing for compatibility with different screen readers.
announcementPriorityannouncement-priority'polite' | 'assertive''polite'ARIA live region politeness level for screen reader announcements. - polite: Announcements wait for current reading to complete (recommended) - assertive: Announcements interrupt current reading

Events

EventDetailDescription
toggleFired when the accordion state changes (expand or collapse). Detail: { expanded: boolean }
expandFired specifically when the accordion expands. Detail: { expanded: boolean }
collapseFired specifically when the accordion collapses. Detail: { expanded: boolean }
transition-endFired when the CSS Grid animation completes. Detail: { expanded: boolean }

Slots

SlotDescription
defaultThe main content displayed when the accordion is expanded
prefixCustom prefix content that overrides the prefix-icon-name property
headerCustom header content that overrides title, subtitle, and optional-text properties
expand-iconCustom expand/collapse indicator that overrides the icon-name property

CSS Parts

PartDescription
baseThe accordion's root container element
headerThe clickable header button element
titleThe title area container (present only when the header slot is used)
prefixThe prefix icon container (only present when prefix content exists)
iconThe expand/collapse icon container
contentThe CSS Grid animated content container
live-regionThe ARIA live region for screen reader announcements (visually hidden)

CSS Custom Properties

PropertyDescription
--hy-accordion-border-default-restBorder color at rest
--hy-accordion-border-subtle-restSubtle border color
--hy-accordion-strokeBorder width
--hy-accordion-radiusBorder radius (all four corners)
--hy-accordion-radius-top-startTop-start corner radius override. Defaults to --hy-radius-row-list-md-top-start; cascades through --hy-accordion-radius so a single radius override still shapes all four corners.
--hy-accordion-radius-top-endTop-end corner radius override. See top-start.
--hy-accordion-radius-bottom-startBottom-start corner radius override. See top-start.
--hy-accordion-radius-bottom-endBottom-end corner radius override. See top-start.
--hy-accordion-padding-header-blockHeader block padding
--hy-accordion-padding-inlineInline padding
--hy-accordion-gap-size-smGap for small size
--hy-accordion-gap-size-mdGap for medium size
--hy-accordion-gap-size-lgGap for large size
--hy-accordion-header-gapGap between header elements
--hy-accordion-text-transformText transform for accordion title
--hy-accordion-expand-durationTransition duration for the expand/collapse panel animation
--hy-accordion-expand-easingTransition easing for the expand/collapse panel animation

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.

Built with Lit. Documented with VitePress.