adev/src/content/guide/aria/accordion.md
An accordion organizes related content into expandable and collapsible sections, reducing page scrolling and helping users focus on relevant information. Each section has a trigger button and a content panel. Clicking a trigger toggles the visibility of its associated panel.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.ts"> <docs-code header="TS" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.ts"/> <docs-code header="HTML" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.html"/> <docs-code header="CSS" path="adev/src/content/examples/aria/accordion/src/single-expansion/basic/app/app.css"/> </docs-code-multifile>Accordions work well for organizing content into logical groups where users typically need to view one section at a time.
Use accordions when:
Avoid accordions when:
Set [multiExpandable]="false" to allow only one panel to be open at a time. Opening a new panel automatically closes any previously open panel.
This mode works well for FAQs or situations where you want users to focus on one answer at a time.
Set [multiExpandable]="true" to allow multiple panels to be open simultaneously. Users can expand as many panels as needed without closing others.
This mode is useful for form sections or when users need to compare content across multiple panels.
NOTE: The multiExpandable input defaults to true. Set it to false explicitly if you want single expansion behavior.
Disable specific triggers using the disabled input. Control how disabled items behave during keyboard navigation using the softDisabled input on the accordion group.
When [softDisabled]="true" (the default), disabled items can receive focus but cannot be activated. When [softDisabled]="false", disabled items are skipped entirely during keyboard navigation.
Use the ngAccordionContent directive on an ng-template to defer rendering content until the panel first expands. This improves performance for accordions with heavy content like images, charts, or complex components.
<div ngAccordionGroup>
<div>
<button ngAccordionTrigger [panel]="panel1">Trigger Text</button>
<div ngAccordionPanel #panel1="ngAccordionPanel">
<ng-template ngAccordionContent>
<!-- This content only renders when the panel first opens -->
<app-expensive-component />
</ng-template>
</div>
</div>
</div>
By default, content remains in the DOM after the panel collapses. Set [preserveContent]="false" to remove the content from the DOM when the panel closes.
Angular Aria provides component harnesses for testing accordion components. Here is an example of how to use the harnesses in a component test:
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {AccordionGroupHarness} from '@angular/aria/accordion/testing';
import {MyAccordionComponent} from './my-accordion'; // Your component
describe('MyAccordionComponent', () => {
let fixture: ComponentFixture<MyAccordionComponent>;
let loader: HarnessLoader;
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [MyAccordionComponent],
});
fixture = TestBed.createComponent(MyAccordionComponent);
await fixture.whenStable();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should allow expanding panels', async () => {
// Load the accordion group harness
const group = await loader.getHarness(AccordionGroupHarness);
// Get all individual accordions (items) in the group
const accordions = await group.getAccordions();
expect(accordions.length).toBe(3);
// Verify initial state (first expanded, others collapsed)
expect(await accordions[0].isExpanded()).toBe(true);
expect(await accordions[1].isExpanded()).toBe(false);
// Expand the second panel
await accordions[1].expand();
// Verify updated state
expect(await accordions[1].isExpanded()).toBe(true);
// If multiExpandable is false, the first one should now be collapsed
expect(await accordions[0].isExpanded()).toBe(false);
});
});
For detailed API documentation, inspect the following API references: