Skip to main contentSkip to docs navigation

Create accessible, responsive accordions using HTML5 native elements with Chassis CSS. Features smooth transitions, multiple styling options, and built-in accessibility without extensive JavaScript.

@layer components
JavaScript is optional
Component tokens

How It Works

Chassis accordions leverage the native HTML5 <details> and <summary> elements, providing several key benefits:

  • Native browser functionality: The browser handles expanding and collapsing content without requiring extensive JavaScript
  • Built-in accessibility: Native keyboard navigation and screen reader support through the HTML5 elements
  • Enhanced with JavaScript: While fully functional without JavaScript, our optional JS adds smooth transitions between states
  • Group behavior: Using the same name attribute on multiple <details> elements creates accordion groups where only one item can be open at a time

Chassis CSS respects user accessibility preferences by automatically disabling animations when the prefers-reduced-motion media query is detected. See the reduced motion guidelines in our accessibility documentation for implementation details.

Examples

Click the accordions below to expand/collapse the content. Each item in this example shares the same name="example" attribute, creating a group where only one accordion can be open at a time.

Add the open attribute to any <details> element to render it expanded by default.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
<div class="accordion">
<details name="example" open>
  <summary>
    <span class="accordion-title">Accordion Item #1</span>
  </summary>
  <div class="accordion-body">
    <p>This is the <b>first item's body</b>, shown by default. It will automatically close when another item is opened by clicking its summary element.</p>
  </div>
</details>
<details name="example">
  <summary>
    <span class="accordion-title">Accordion Item #2</span>
  </summary>
  <div class="accordion-body">
    <p>This is the <b>second item's body</b>. It is hidden by default and will open when its summary element is clicked.</p>
  </div>
</details>
<details name="example">
  <summary>
    <span class="accordion-title">Accordion Item #3</span>
  </summary>
  <div class="accordion-body">
    <p>This is the <b>third item's body</b>. It is hidden by default and will open when its summary element is clicked.</p>
  </div>
</details>
</div>

Headings

The HTML spec permits one heading element as a direct child of <summary> — no ARIA role overrides are needed. Use a heading element as .accordion-title when accordion headers need to participate in the document's visual and source-order hierarchy.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
<div class="accordion">
<details name="example-headings" open>
  <summary>
    <h3 class="accordion-title">Accordion Item #1</h3>
  </summary>
  <div class="accordion-body">
    <p>This is the <b>first item's body</b>, shown by default. It will automatically close when another item is opened by clicking its summary element.</p>
  </div>
</details>
<details name="example-headings">
  <summary>
    <h3 class="accordion-title">Accordion Item #2</h3>
  </summary>
  <div class="accordion-body">
    <p>This is the <b>second item's body</b>. It is hidden by default and will open when its summary element is clicked.</p>
  </div>
</details>
<details name="example-headings">
  <summary>
    <h3 class="accordion-title">Accordion Item #3</h3>
  </summary>
  <div class="accordion-body">
    <p>This is the <b>third item's body</b>. It is hidden by default and will open when its summary element is clicked.</p>
  </div>
</details>
</div>

The heading level does not appear in assistive technology heading navigation — inside a disclosure button, heading semantics are absorbed into the button role. Accordion headers remain fully accessible via keyboard and button navigation. When heading-outline navigation is a strict requirement, use the WAI-ARIA APG accordion pattern instead.

Static Items

Accordions with the same name attribute form groups that close automatically when another item in the group is opened. Items without a name attribute (or with unique names) remain independent. You can mix both types in a single accordion.

Accordion Item #1

This is the first item's body, shown by default. Since it has no name attribute, it behaves independently and will only close when its own summary element is clicked.

Accordion Item #2

This item shares the example-static name attribute with Accordion Item #3, forming a group. It will automatically close when Accordion Item #3 is opened.

Accordion Item #3

This item shares the example-static name attribute with Accordion Item #2, forming a group. It will automatically close when Accordion Item #2 is opened.

HTML
<div class="accordion">
  <details open>
    <summary>
      <span class="accordion-title">Accordion Item #1</span>
    </summary>
    <div class="accordion-body">
      <p>This is the first item's body, shown by default. Since it has <b>no name attribute</b>, it behaves independently and will only close when its own summary element is clicked.</p>
    </div>
  </details>
  <details name="example-static" open>
    <summary>
      <span class="accordion-title">Accordion Item #2</span>
    </summary>
    <div class="accordion-body">
      <p>This item shares the <b>example-static</b> name attribute with Accordion Item #3, forming a group. It will automatically close when <b>Accordion Item #3</b> is opened.</p>
    </div>
  </details>
  <details name="example-static">
    <summary>
      <span class="accordion-title">Accordion Item #3</span>
    </summary>
    <div class="accordion-body">
      <p>This item shares the <b>example-static</b> name attribute with Accordion Item #2, forming a group. It will automatically close when <b>Accordion Item #2</b> is opened.</p>
    </div>
  </details>
</div>

Flush Accordion

Add .flush to remove some borders and rounded corners to render accordions edge-to-edge with their parent container.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
  <div class="accordion flush">
    ...
  </div>

Caret Position

Add .caret-end to the accordion container to move the caret icon to the end of the summary element.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
  <div class="accordion caret-end">
    ...
  </div>

Disable Animation

Add .no-transition to the accordion container to disable the smooth transition effect.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
  <div class="accordion no-transition">
    ...
  </div>

Sizes

In Figma

Chassis CSS offers size variations to help accordions integrate seamlessly with different UI contexts. Adjust sizes to establish visual hierarchy and optimize space utilization based on your layout requirements.

Large

Add .large for larger font size and more generous spacing. Suitable for primary content areas, FAQ sections, or hero elements where accordions need more visual prominence.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
  <div class="accordion large">
    ...
  </div>

Small

Add .small for reduced font size and compact spacing. Suitable for secondary content areas like cards, sidebars, or dense layouts where space efficiency is a priority.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
<div class="accordion small">
  ...
</div>

Context Variants

CSS Only

You can use the .context class to add a color or style to the accordion. The context class is used to apply a specific color scheme or style to the accordion, making it visually distinct and aligned with your design preferences. See context class for more information.

Colors

Use .context class on accordion with a color, like .primary.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
<div class="accordion context neutral small">
  ...
</div>

<div class="accordion context primary small">
  ...
</div>

<div class="accordion context secondary small">
  ...
</div>

<div class="accordion context alternate small">
  ...
</div>

Styles

Use .context class on accordions with a color and style, like .primary and .solid.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #1

This is the first item's body, shown by default. It will automatically close when another item is opened by clicking its summary element.

Accordion Item #2

This is the second item's body. It is hidden by default and will open when its summary element is clicked.

Accordion Item #3

This is the third item's body. It is hidden by default and will open when its summary element is clicked.

HTML
<div class="accordion context primary small">
  ...
</div>

<div class="accordion context primary solid small">
  ...
</div>

<div class="accordion context primary smooth small">
  ...
</div>

<div class="accordion context primary outline small">
  ...
</div>

Accessibility

The accordion component leverages the native HTML5 <details> and <summary> elements, which provide built-in accessibility features including keyboard navigation, focus management, and appropriate ARIA states without additional JavaScript. This ensures users of assistive technologies can interact with accordions using standard navigation patterns.

Using Headings

The HTML spec permits one heading element as a direct child of <summary>. No ARIA role overrides are needed — place the heading inside <summary> and the browser handles button semantics and aria-expanded state automatically.

HTML
<details>
  <summary>
    <h3 class="accordion-title">Accordion Item #1</h3>
  </summary>
  <div class="accordion-body">
    <!-- Content -->
  </div>
</details>

Screen readers announce the header as a disclosure button using the heading text as its accessible name. The <summary> retains its native role="button" and the browser reflects the open attribute as aria-expanded without JavaScript.

The heading level does not appear in assistive technology heading-outline navigation. Inside a disclosure button, heading semantics are absorbed into the button role — the heading element contributes its text as the button's accessible name, but its level is not exposed in the document outline. Accordion headers are discoverable via button and form-control navigation but not via heading shortcuts (h-key in NVDA, JAWS, or VoiceOver).

When AT heading-outline navigation is a hard requirement, the WAI-ARIA APG accordion pattern uses <h3><button> markup that participates in both heading and button navigation — at the cost of abandoning the native <details> element and requiring full JavaScript state management.

CSS

This component can be customized through Sass variables at compile time.

Custom properties

This component exposes CSS custom properties to control its appearance at runtime.

--border-color: var(--accordion-border-color, #{$accordion-border-color});
--border-width: var(--accordion-border-width, #{$accordion-border-width});
--border-radius: var(--accordion-border-radius, #{$accordion-border-radius});
--inner-border-radius: var(--accordion-inner-border-radius, #{$accordion-inner-border-radius});
--transition: var(--accordion-transition, #{$accordion-transition});
--item-fg-color: var(--accordion-item-fg-color, #{$accordion-item-fg-color});
--item-bg-color: var(--accordion-item-bg-color, #{$accordion-item-bg-color});
// Accordion title
--title-padding-y: var(--accordion-title-padding-y, #{$accordion-title-padding-y});
--title-padding-x: var(--accordion-title-padding-x, #{$accordion-title-padding-x});
--title-gap: var(--accordion-title-gap, #{$accordion-title-gap});
--title-fg-color: var(--accordion-title-fg-color, #{$accordion-title-fg-color});
--title-bg-color: var(--accordion-title-bg-color, #{$accordion-title-bg-color});
--title-fg-active: var(--accordion-title-fg-active, #{$accordion-title-fg-active});
--title-bg-active: var(--accordion-title-bg-active, #{$accordion-title-bg-active});
@include map-font($accordion-title-font, accordion, title);
--title-transition: var(--accordion-title-transition, #{$accordion-title-transition});
// Accordion body
--body-padding-t: var(--accordion-body-padding-t, #{$accordion-body-padding-t});
--body-padding-b: var(--accordion-body-padding-b, #{$accordion-body-padding-b});
--body-padding-s: var(--accordion-body-padding-s, #{$accordion-body-padding-s});
--body-padding-e: var(--accordion-body-padding-e, #{$accordion-body-padding-e});
@include map-font($accordion-body-font, accordion, body);
// Accordion caret
--caret-icon: var(--accordion-caret-icon, #{svg-icon($accordion-caret-icon)});
--caret-size: var(--accordion-caret-size, #{$accordion-caret-size});
--caret-idle-color: var(--accordion-caret-idle-color, #{$accordion-caret-idle-color});
--caret-active-color: var(--accordion-caret-active-color, #{$accordion-caret-active-color});
--caret-transform: var(--accordion-caret-transform, #{$accordion-caret-transform});
--caret-transition: var(--accordion-caret-transition, #{$accordion-caret-transition});

Sass variables

This component uses Sass variables in scss/config/_defaults.scss to define its defaults.

$accordion-inner-border-radius:         calc($accordion-border-radius - $accordion-border-width);
$accordion-transition:                  $transition-collapse;
$accordion-title-transition:            $button-transition, border-radius .15s ease;
$accordion-caret-transition:            $caret-transition;
$accordion-caret-transform:             rotate(-180deg);
$accordion-focus-ring-offset:           0px;
// Accordion context variables are not exposed as CSS variables.
$accordion-item-fg-color-context:       var(--fg-main);
$accordion-item-bg-color-context:       var(--bg-main);
$accordion-title-fg-color-context:      var(--fg-main);
$accordion-title-bg-color-context:      var(--bg-main);
$accordion-title-fg-active-context:     var(--fg-main);
$accordion-title-bg-active-context:     var(--bg-main);
$accordion-caret-idle-context:          var(--icon-subtle);
$accordion-caret-active-context:        var(--icon-main);
$accordion-border-color-context:        var(--border-subtle);

Design tokens

This component consumes design tokens from Chassis Tokens with the $cx- prefix. — See thedesign tokens page.

// Font
$accordion-title-font:                    $cx-font-accordion-medium-title;
$accordion-body-font:                     $cx-font-accordion-medium-body;
$accordion-large-title-font:              $cx-font-accordion-large-title;
$accordion-large-body-font:               $cx-font-accordion-large-body;
$accordion-small-title-font:              $cx-font-accordion-small-title;
$accordion-small-body-font:               $cx-font-accordion-small-body;
// Color
$accordion-item-fg-color:                 $cx-color-accordion-item-fg-color;
$accordion-item-bg-color:                 $cx-color-accordion-item-bg-color;
$accordion-title-fg-color:                $cx-color-accordion-title-fg-idle;
$accordion-title-bg-color:                $cx-color-accordion-title-bg-idle;
$accordion-title-fg-active:               $cx-color-accordion-title-fg-active;
$accordion-title-bg-active:               $cx-color-accordion-title-bg-active;
$accordion-caret-idle-color:              $cx-color-accordion-indicator-idle;
$accordion-caret-active-color:            $cx-color-accordion-indicator-active;
$accordion-border-color:                  $cx-color-accordion-border-main;
// Size
$accordion-caret-size:                    $cx-size-accordion-medium-indicator;
$accordion-large-caret-size:              $cx-size-accordion-large-indicator;
$accordion-small-caret-size:              $cx-size-accordion-small-indicator;
// Spacing
$accordion-title-padding-y:               $cx-space-accordion-medium-title-padding-y;
$accordion-title-padding-x:               $cx-space-accordion-medium-title-padding-x;
$accordion-title-gap:                     $cx-space-accordion-medium-gap;
$accordion-body-padding-t:                $cx-space-accordion-medium-body-padding-t;
$accordion-body-padding-b:                $cx-space-accordion-medium-body-padding-b;
$accordion-body-padding-s:                $cx-space-accordion-medium-body-padding-s;
$accordion-body-padding-e:                $cx-space-accordion-medium-body-padding-e;
$accordion-large-title-padding-y:         $cx-space-accordion-large-title-padding-y;
$accordion-large-title-padding-x:         $cx-space-accordion-large-title-padding-x;
$accordion-large-title-gap:               $cx-space-accordion-large-gap;
$accordion-large-body-padding-t:          $cx-space-accordion-large-body-padding-t;
$accordion-large-body-padding-b:          $cx-space-accordion-large-body-padding-b;
$accordion-large-body-padding-s:          $cx-space-accordion-large-body-padding-s;
$accordion-large-body-padding-e:          $cx-space-accordion-large-body-padding-e;
$accordion-small-title-padding-y:         $cx-space-accordion-small-title-padding-y;
$accordion-small-title-padding-x:         $cx-space-accordion-small-title-padding-x;
$accordion-small-title-gap:               $cx-space-accordion-small-gap;
$accordion-small-body-padding-t:          $cx-space-accordion-small-body-padding-t;
$accordion-small-body-padding-b:          $cx-space-accordion-small-body-padding-b;
$accordion-small-body-padding-s:          $cx-space-accordion-small-body-padding-s;
$accordion-small-body-padding-e:          $cx-space-accordion-small-body-padding-e;
// Borders
$accordion-border-width:                  $cx-border-width-accordion-main;
$accordion-border-radius:                 $cx-border-radius-accordion-main;
// Icon
$accordion-caret-icon:                    $cx-icon-accordion-indicator;