Accordion
Accordions are collapsible content containers that let users reveal or hide sections of content. They reduce cognitive load by surfacing only the most relevant content on first glance and letting users choose how deep to dig.
Ready to use
This component is fully responsive and intentionally designed to be used across all viewports — mobile, tablet, and desktop — with no alternative versions required.
Anatomy
Section titled “Anatomy”- Header
- Icon
- Divider
- Panel
When to use it
Section titled “When to use it”Use the accordion when:
- You need to present several groups of related information, but not all of it needs to be visible at once.
- You want to reduce visual clutter and keep the page easier to scan.
- Users may only need to access some details depending on their specific needs or interests.
- You want to avoid long scrolling, especially on mobile devices or content-dense pages.
- The content in each section can be understood independently from the rest.
Avoid the accordion when:
- The content is essential for understanding the page and should remain visible without interaction.
- Users need to compare information across multiple sections at the same time.
- The page only contains one section of information (in that case, display it directly).
- Frequent opening and closing would interrupt the user’s workflow or slow them down.
Properties
Section titled “Properties”Header
The trigger row that toggles the accordion. Always keyboard-focusable; the title text doubles as the accessible name.
Icon
A chevron that rotates between collapsed and expanded states. Decorative — the open/closed state is also conveyed via aria-expanded.
Divider
A 1px line separating consecutive items. Adopts the contrast or neutral border token depending on the surrounding scheme.
Panel
The collapsible content region. Hidden from assistive tech when collapsed and revealed in document order when expanded.
Platform considerations
Section titled “Platform considerations”Desktop
On desktop the full accordion stack is visible at once. Keep the trigger row tall enough for comfortable pointer targets and let the panel content flow naturally without artificial caps.
Tablet
The same stack adapts to narrower widths. Respect the 44×44 px touch target on the header so the component remains comfortable to tap.
Mobile
On mobile, prefer single-item expansion to reduce scroll jumps. Keep titles short so they fit on a single line at the smallest breakpoint.
Best practices
Section titled “Best practices”Use the accordion to progressively disclose detail — never to bury content users actually need.
Do
Group related items, write concise scannable titles, and keep consistent spacing between accordions to support visual rhythm.
Don't
Avoid nesting accordions, hiding essential information, or stacking more items than a user can reasonably scan in one view.
Content guidelines
Section titled “Content guidelines”Keep titles short and scannable — typically one line. Lead with the keyword that helps users identify the content at a glance, and use sentence case for readability (for example “Account details”, not “ACCOUNT DETAILS”). When several accordions sit together, write titles in parallel structure (all nouns or all verbs) so the group reads as a coherent set. Avoid hiding content that users need on every visit; if it’s critical, show it directly instead.
Styles
Section titled “Styles”The accordion can leverage <details> and <summary> elements, providing built-in expand/collapse behavior without JavaScript.
<details class="tng-accordion"> <summary class="tng-accordion-trigger"> <span>Accordion title</span> <i class="tng-icon icon-chevron-down" aria-hidden="true"></i> </summary> <p class="tng-text-body"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p></details>Accordion title
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Accordion title
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Elements
Section titled “Elements”Add an icon before the title for visual context.
<details class="tng-accordion"> <summary class="tng-accordion-trigger"> <i class="tng-icon icon-profile" aria-hidden="true"></i> <span>Account details</span> <i class="tng-icon icon-chevron-down" aria-hidden="true"></i> </summary> <p class="tng-text-body"> Manage your account settings and preferences. </p></details>Account details
Manage your account settings and preferences.
Account details
Manage your account settings and preferences.
Modules
Section titled “Modules”Accordion group
Section titled “Accordion group”Multiple accordions can be stacked using our flex layout, optionally adding a divider.
<div class="tng-stack gap-none align-items-stretch | tng-has-dividers"> <details class="tng-accordion" open> <summary class="tng-accordion-trigger"> <i class="tng-icon icon-profile" aria-hidden="true"></i> <span>Personal information</span> <i class="tng-icon icon-chevron-down" aria-hidden="true"></i> </summary> <div class="tng-slot is-primary"></div> <p class="tng-text-body"> Your personal information is kept private and secure. </p> </details> <button class="tng-button is-lg is-tertiary is-ghost pb-xl | justify-content-space-between" > Inline Button <i class="tng-icon icon-external-link" aria-hidden="true"></i> </button> <details class="tng-accordion"> <summary class="tng-accordion-trigger"> <i class="tng-icon icon-settings" aria-hidden="true"></i> <span>Settings</span> <i class="tng-icon icon-chevron-down" aria-hidden="true"></i> </summary> <p class="tng-text-body"> Configure your preferences and settings. </p> </details> <details class="tng-accordion"> <summary class="tng-accordion-trigger"> <i class="tng-icon icon-info" aria-hidden="true"></i> <span>Help & Support</span> <i class="tng-icon icon-chevron-down" aria-hidden="true"></i> </summary> <p class="tng-text-body"> Get help with common issues and contact support. </p> </details></div>Personal information
Your personal information is kept private and secure.
Settings
Configure your preferences and settings.
Help & Support
Get help with common issues and contact support.
Personal information
Your personal information is kept private and secure.
Settings
Configure your preferences and settings.
Help & Support
Get help with common issues and contact support.
Import the Accordion and AccordionItem components from @tmedxp/react-components.
Properties
Section titled “Properties”AccordionProperties extends PropsWithChildren<ComponentProps<'div'>>, meaning it includes all standard HTML attributes that can be applied to a <div>.
| Prop | Type | Description | Optional |
|---|---|---|---|
className | string | Custom classNames you want to apply to the accordion. | ✅ |
children | React.ReactElement<typeof AccordionItem> | React.ReactElement<typeof AccordionItem>[] | Set of accordion items. | ❌ |
hasDivider | boolean | Display or not a divider. Displayed by default. | ✅ |
AccordionItem properties
Section titled “AccordionItem properties”AccordionItemProperties extends PropsWithChildren<ComponentProps<'details'>>, meaning it includes all standard HTML attributes that can be applied to a <details>.
| Prop | Type | Description | Optional |
|---|---|---|---|
className | string | Custom classNames you want to apply to the accordion. | ✅ |
title | string | The accordion title. | ❌ |
iconName | IconProperties['name'] | The accordion icon name. | ✅ |
children | React.ReactElement | The accordion content. | ❌ |
open | boolean | HTML property. Defines the initial accordion state. | ✅ |
Example
Section titled “Example”import { Accordion, AccordionItem } from '@tmedxp/react-components';
const ExampleAccordion = (items) => { return ( <Accordion id="accordion-simple"> {items.map((item, key) => ( <AccordionItem key={key} title={item.title} name={item.name} open={item.open} hasDivider={item.hasDivider} iconName={item.iconName} > <div dangerouslySetInnerHTML={{ __html: item.HTMLContent }} /> </AccordionItem> ))} </Accordion> );};
export { ExampleAccordion };Quick summary
Section titled “Quick summary”- The accordion must be fully operable with the keyboard. Users should be able to navigate to the header and toggle it using Enter or Space.
- The header must behave as an interactive element with a clear focus state, so users can easily see where they are.
- Open and closed states must be communicated both visually and programmatically. This includes a clear change in icon direction or state indicator, and appropriate ARIA attributes (
aria-expanded,aria-controls). - The content panel should be associated with its header via unique IDs for clear screen-reader navigation.
- Text and icon contrast must meet WCAG AA standards to support readability in different environments.
- The component should follow consistent spacing, typography, and motion guidelines from the design system to reinforce predictable behavior across the interface.
For designers
Section titled “For designers”- All accordion states (collapsed, expanded, hover, and focus) must maintain accessible contrast in both light and dark background contexts.
- Focus styles must remain visible and meet WCAG AA contrast requirements across all supported surfaces. Focus should be clearly distinguishable from hover.
- Interaction feedback (hover, expanded) must use more than colour alone to convey state — for example icon rotation, border emphasis, or background changes.
- Colour tokens used within the accordion should be semantic (e.g.
color-foreground-neutral-default) rather than fixed values. This ensures the accordion adapts correctly to different themes or surfaces. - The icon indicating the open/closed state must have a clear and consistent visual transformation (e.g. rotation) and should not rely on colour alone.
Contrast compliance — Toyota
Section titled “Contrast compliance — Toyota”| State | Label colour | Border colour | Contrast ratio | Passes WCAG AA? |
|---|---|---|---|---|
| Rested | #FFFFFF | #282830 | 11.5:1 | ✅ Yes |
| Hover | #15151B | #A8AAAC | 11.5:1 | ✅ Yes |
| Expanded | #15151B | #282830 | 11.5:1 | ✅ Yes |
For developers
Section titled “For developers”The accordion leverages native <details> and <summary> elements, which provide built-in accessibility:
- Enter and Space toggle the panel.
- The browser exposes the expanded/collapsed state to assistive technologies automatically.
- No ARIA attributes are required when using native elements.
Accordion group
Section titled “Accordion group”- Use the
nameattribute on<details>elements to create an exclusive accordion group (only one open at a time). - Mark decorative icons (like the chevron) with
aria-hidden="true"so screen readers skip them.
Implementation checklist
Section titled “Implementation checklist”To meet WCAG 2.1 AA and support assistive technologies, follow these implementation standards:
- Semantic HTML
- Prefer
<details>+<summary>. If building a custom accordion, use a semantic<button>for the header — do not use<div>or<span>with click handlers. - The content region must be associated with the header via
aria-controlsandaria-expanded.
- Prefer
- Keyboard navigation
- Accordion headers must be reachable via Tab.
- Panels must toggle open/closed with Enter and Space.
- If the accordion is part of a multi-expand list, arrow-key navigation may be supported as an enhancement.
- Screen-reader support
- The header text must clearly describe the content it controls.
- The panel may use
role="region"and reference the header witharia-labelledbyoraria-controls. - Icon-only headers are not permitted; they must include visible text or an accessible label.
- Interaction feedback
- Expanded state must be announced via
aria-expanded. - Visual changes should reinforce state (icon rotation, background, border).
- Avoid relying solely on colour to indicate open/closed status.
- Expanded state must be announced via
- Responsive and tap targets
- The accordion header’s interactive area must be at least 44 px in height to support touch accessibility.
Good vs bad
Section titled “Good vs bad”| Case | ✅ Good | ❌ Bad |
|---|---|---|
| Semantic structure | <button aria-expanded="true">… | <div onclick="toggle()">… |
| Keyboard navigation | Toggles using Enter / Space | Only toggles with pointer click |
| Focus visibility | Clear, high-contrast focus ring | Focus removed or replaced by hover-only styling |
| Open/closed state | Icon rotation + aria-expanded + background shift | Only colour change with no semantic state |