Canvas Design System
Main Site Tokens

Accordion

Expandable content panels for FAQs and collapsible sections. Supports bordered variant, icons, and multiple-open mode.

When to Use

Use Accordion when: Presenting FAQs, step-by-step instructions, or long lists of content that users need to scan quickly. Accordions reduce page length while keeping all information accessible.
Don't use when: All content should be visible at once (e.g. a short form). If there are only 2 items, consider showing them inline. For navigation, use Tabs instead.

Default

Workshopr is a platform for workshop facilitators featuring a content library and AI Facilitation Coach.

<?= ws_accordion([
    ['title' => 'Question 1', 'content' => 'Answer 1', 'open' => true],
    ['title' => 'Question 2', 'content' => 'Answer 2'],
]) ?>

Bordered Variant

<?= ws_accordion($items, ['variant' => 'bordered']) ?>

Allow Multiple Open

By default, opening a panel closes others. Set multiple: true to allow several panels open at once.

This accordion allows multiple panels to be open simultaneously.

Click to open without closing the other panels.

<?= ws_accordion($items, ['multiple' => true]) ?>

With Icons

Each item can have an optional Material icon to add visual context.

<?= ws_accordion([
    ['title' => 'Design Sprint', 'content' => '...', 'icon' => 'design_services'],
    ['title' => 'Retrospective', 'content' => '...', 'icon' => 'history'],
], ['variant' => 'bordered']) ?>

Parameters

Accordion Options

ParameterTypeDefaultDescription
idstringauto-generatedContainer element ID
variantstringdefaultdefault | bordered | flush
sizestringmdsm | md | lg
multipleboolfalseAllow multiple panels open at once
classstring''Additional CSS classes

Item Options

ParameterTypeDefaultDescription
titlestringPanel heading text
contentstringPanel body HTML
openboolfalseInitially expanded
iconstringnullMaterial icon name
disabledboolfalsePrevent interaction

Anatomy

.ws-accordion — Outer container
.ws-accordion__item — Individual panel wrapper
.ws-accordion__trigger — Clickable header button
.ws-accordion__icon — Optional leading icon
.ws-accordion__title — Heading text
.ws-accordion__arrow — Expand/collapse chevron
.ws-accordion__panel — Collapsible content region

CSS Classes

ClassPurpose
.ws-accordionBase accordion styles
.ws-accordion--defaultDefault variant
.ws-accordion--borderedBordered variant with card-style panels
.ws-accordion--flushFlush variant (no borders)
.ws-accordion--sm / --md / --lgSize modifiers
.ws-accordion__item.is-openOpen/expanded state
.ws-accordion__item.is-disabledDisabled state

Accessibility

The accordion follows the WAI-ARIA Accordion pattern.

ARIA Attributes

ElementAttributeValue
.ws-accordion__triggerrolebutton (implicit if <button>)
.ws-accordion__triggeraria-expandedtrue (open) | false (collapsed)
.ws-accordion__triggeraria-controlsID of the associated panel region
.ws-accordion__triggeraria-disabledtrue when item is disabled
.ws-accordion__panelroleregion
.ws-accordion__panelaria-labelledbyID of the associated trigger button

Keyboard Navigation

KeyBehavior
Enter / SpaceToggles the focused accordion panel open or closed
TabMoves focus to the next focusable element (next trigger or panel content)
/ Moves focus between accordion triggers (when focus is on a trigger)
HomeMoves focus to the first accordion trigger
EndMoves focus to the last accordion trigger

Implementation Notes

Do: Use <button> elements for triggers so they're focusable and activatable by default. The aria-expanded attribute updates dynamically as panels open and close. Heading elements wrapping triggers should match the page outline level.
Don't: Don't remove collapsed panels from the DOM — use hidden or CSS to hide them. Animated expand/collapse should not rely on display: none toggling, which can interrupt screen reader announcements mid-transition.

Files

FilePurpose
includes/components/helpers.phpws_accordion() helper function
includes/components/accordion.phpAccordion template
includes/components/components.cssAccordion CSS (.ws-accordion rules)
includes/components/components.jswsAccordionInit() toggle logic