The page navigation is complete. You may now navigate the page content as you wish.
Skip to main content

An accordion is a vertically stacked list of container-like toggles that reveal or hide associated sections of content.

The accordion is used to show and hide multiple sections of content in a stacked manner. Each section is represented by a toggle.

Usage

When to use

  • To show content as needed while keeping the UI organized and visually manageable.
  • To hide long pieces of content with a similar structure.

When not to use

  • To hide basic non-critical information to users. Instead, consider using a Reveal.
  • To allow users switch between different content within the same context. Instead, consider using Tabs.

Accordion vs Reveal

While similar in functionality and interaction, the Accordion and Reveal are meant to be used in different scenarios and use cases.

When to use the Accordion

  • You have multiple sections of content that can be expanded or collapsed.

  • Each section of content has its own toggle content, giving users the ability to access specific sections.

  • Users need to navigate through different sections of content and selectively expand or collapse sections

  • There is a sequential or hierarchical relationship between the different sections.

When to use the Reveal

  • You have a single piece of content that can be expanded to collapsed to reveal additional details or information.

  • The content within the toggle is plain text.

  • The content within the reveal is relatively short and simple.

  • There is no need for multiple independent sections or hierarchical relationship between different sections.

Usage examples

Do

Use the Accordion when you need to display content in different sections that have a sequential or hierarchical relationship between them.

Accordion with basic content

Don’t

Don’t use the Accordion when you need to display a single piece of content that can expand and collapse. Use the Reveal instead.

Accordion with basic content

Do

Use the Accordion when the toggle or the content is relatively complex.

Accordion with complex content

Sizes

The Accordion comes in three sizes: small, medium, and large. We recommend medium for most use cases, but use whichever size best fits your UI’s needs.

Example of various Accordion sizes

Don’t

The size is set at the Accordion (group) level; don’t mix different sizes of Accordion items. This is a Figma-only issue.

Example of incorrectly combined Accordion sizes

Types

The Accordion offers two container types: card and flush to fit different use cases.

Card

The card variant is the default and recommended type. It creates a visual separation between accordion sections and other UI elements, organizes blocks of content, and distinguishes between sections within tabs.

Do

Example of appropriate usage of the Accordion card variant

Flush

Use the flush variant where space is limited such as within a Card, Flyout, or sidebar.

Do

Example of recommended usage of the Flush variant

Toggle

Toggle type

The toggle accepts many different types of content, from text-based content to nested HDS components or generic content.

Toggle type with basic text

Toggle type with basic text

Toggle type with generic content

Toggle type with generic content

Interactive

Use containsInteractive when nesting interactive content in the toggle. This lets users using assistive technology, access and interact with the nested element.

When using this property, it should be applied to all items. Avoid mixing with default toggles.

Use this variant only when you need to put interactive elements such as a button or a link within the toggle area. Avoid placing complex elements that may compromise the usability and accessibility of the component.

Example of toggle content

Static

The isStatic property removes the the ability to interact with the AccordionItem toggle, keeping it fixed in either an open or closed state based on the isOpen property. This is useful when you want to show important information in the Accordion that should always stay open or closed, making it stand out as different from the other items.

This example depicts the isStatic property being used to prevent interaction with a skipped step in a triggered Terraform run.

Example of a Terraform run with a closed static AccordionItem

Example of a Terraform run with an open static AccordionItem

Content type

The content type property is only relevant within Figma and doesn’t exist as a property in the code.

Content type supports any generic content, local components, or Helios components via an instance swap property (genericInstance) in Figma. In code, yield is supported.

Content type with basic text

Content type with basic text

Content type with generic content

Content type with generic content

Nesting Accordions

Nesting Accordions is only supported in code, as Figma does not support nesting an instance inside itself.

While you can work around this by detaching the HDS component and turning it into a local component, then inserting the local component within the linked HDS component, we do not recommend this approach. Doing so means your local Accordion component will not receive future updates.

Nesting Accordions can help organize complex content, but should be used in moderation, and is only recommended for the flush variant.

Do

Use nested Accordions for up to two layers of related content. You can nest flush Accordions within each other or inside card type Accordions.

Example of a flush Accordion nested inside of a card within another flush Accordion

Don’t

Avoid nesting card Accordions within each other to prevent excessive visual noise.

Incorrect example of two card variants nested within each other

Composition with other components

Expand and collapse all accordions

By composing the Accordion with other HDS components, you can provide users with a way to expand and collapse all AccordionItems at once. Expanding all AccordionItems allows users to view and compare content easily, while collapsing provides a summary and reduces cognitive load.

We recommend using a secondary Button above the Accordion, aligned to the right. A tertiary Button can be used if less prominence is needed. Use the small variant of the Button for any size variant of the Accordion.

To ensure consistency across all products, use “Expand all” / “Collapse all” as the Button label and the unfold-open and unfold-close icons in the leading position.

Secondary & tertiary button examples used for “Expand all” and “Collapse all” functionality

Note that if an AccordionItem is static, the expand/collapse all feature will not affect its behavior.

Don’t

Avoid using this feature if only one AccordionItem is visible.

show example of terraform roles flyout design

How to use this component

The Accordion component is used to wrap and group one or more Accordion::Item child components. The Accordion items consist of “toggle” and “content” named blocks containing plain text or HTML content.

Size

A different size of Accordion can be invoked using the @size argument.

Item one
Item two
  <Hds::Accordion @size="large" as |A|>
    <A.Item>
      <:toggle>Item one</:toggle>
      <:content>
        Additional content for item one
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Item two</:toggle>
      <:content>
        Additional content for item two
      </:content>
    </A.Item>
  </Hds::Accordion>

Type

Use the @type argument to render a flush Accordion.

Item one
Item two
  <Hds::Accordion @type="flush" as |A|>
    <A.Item>
      <:toggle>Item one</:toggle>
      <:content>
        Additional content for item one
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Item two</:toggle>
      <:content>
        Additional content for item two
      </:content>
    </A.Item>
  </Hds::Accordion>

Complex HTML content

With an Alert component in the toggle block and an HTML table in the content block.

Queued: 9 days ago > Finished: 9 days ago

Example table
Name Type Value
Cell one A Cell two A Cell three A
Cell one B Cell two B Cell three B
  <Hds::Accordion as |A|>
    <A.Item @isOpen={{true}}>
      <:toggle>
        <Hds::Alert @type="compact" @color="success" as |A|>
          <A.Title>Title</A.Title>
          <A.Description>Plan finished <small>22 days ago</small></A.Description>
        </Hds::Alert>
      </:toggle>
      <:content>
        <p class="hds-typography-body-200">
          <strong>Queued:</strong>
          9 days ago >
          <strong>Finished:</strong>
          9 days ago
        </p>
        <Hds::Table @caption="Example table">
          <:head as |H|>
            <H.Tr>
              <H.Th>Name</H.Th>
              <H.Th>Type</H.Th>
              <H.Th>Value</H.Th>
            </H.Tr>
          </:head>
          <:body as |B|>
            <B.Tr>
              <B.Td>Cell one A</B.Td>
              <B.Td>Cell two A</B.Td>
              <B.Td>Cell three A</B.Td>
            </B.Tr>
            <B.Tr>
              <B.Td>Cell one B</B.Td>
              <B.Td>Cell two B</B.Td>
              <B.Td>Cell three B</B.Td>
            </B.Tr>
          </:body>
        </Hds::Table>
      </:content>
    </A.Item>
  </Hds::Accordion>

With a link in the toggle block and a form in the content.

Text inside a nested div with a link.
  <Hds::Accordion as |A|>
    <A.Item @containsInteractive={{true}} @isOpen={{true}}>
      <:toggle>
        <div class="hds-typography-body-300">
          Text inside a nested div with <a href="https://www.hashicorp.com/">a link</a>.
        </div>
      </:toggle>
      <:content>
        <p>
          <Hds::Form::TextInput::Field @type="email" as |F|>
            <F.Label>Email</F.Label>
          </Hds::Form::TextInput::Field>
        </p>
        <Hds::Button @text="Submit" />
      </:content>
    </A.Item>
  </Hds::Accordion>

With an Accordion in the content block.

Item one
Nested item one
Nested item two
  <Hds::Accordion @type="flush" as |A|>
    <A.Item @isOpen={{true}}>
      <:toggle>Item one</:toggle>
      <:content>
        <Hds::Accordion @type="flush" as |AA|>
          <AA.Item>
            <:toggle>Nested item one</:toggle>
            <:content>Nested content one</:content>
          </AA.Item>
          <AA.Item>
            <:toggle>Nested item two</:toggle>
            <:content>Nested content two</:content>
          </AA.Item>
        </Hds::Accordion>
      </:content>
    </A.Item>
  </Hds::Accordion>

Expand and collapse all

The @forceState argument enables you to implement expand/collapse all functionality by programmatically controlling the states of all items within a group. The @forceState argument may also be used at item level if further granularity is required.

Examination period
Exam experience
Requirements for attending an exam
Your badge and certificate
Renewing your certification
Finding certified practitioners
  <div class="doc-accordion-flex-layout">
    <Hds::Text::Display @size="300">Examination period</Hds::Text::Display>
    <Hds::Button
      @text={{if (eq this.state "open") "Collapse all" "Expand all"}}
      @icon={{if (eq this.state "open") "unfold-close" "unfold-open"}}
      @color="tertiary" @size="small" {{on "click" this.toggleState}}
    />
  </div>
  <Hds::Accordion @forceState={{this.state}} as |A|>
    <A.Item>
      <:toggle>Exam experience</:toggle>
      <:content>
        All certification exams are taken online with a live proctor, accommodating all locations and time zones. Online proctoring provides the same benefits of a physical test center while being more accessible to exam-takers. The live proctor verifies your identity, walks you through rules and procedures, and watches you take the exam. Learn more ways to prepare for an online proctored exam in our Knowledgebase.
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Requirements for attending an exam</:toggle>
      <:content>
        Before you register for an exam, review the Exam-taker Handbook to learn the requirements and policies for taking exams. It is your responsibility to know and abide by our program rules to successfully enter your exam appointment, failure to do so may result in forfeiture of appointment fees.        
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Your badge and certificate</:toggle>
      <:content>
        HashiCorp has partnered with Credly to offer you a digital badge and downloadable certificate upon passing a certification exam. There is no fee for this service and acceptance is up to you. Digital badges can be used in email signatures or digital resumes, and on social media sites such as LinkedIn, Facebook, and Twitter. Badges link back to a real-time verification feature that describes your qualifications.
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Renewing your certification</:toggle>
      <:content>
        All HashiCorp Certifications are valid for two years, and you will be eligible to renew your certification starting 18 months after you earned your certification. To recertify, you will need to pass an exam at the same level or higher for the certification you are looking to renew. There are several pathways to recertification available, and you can learn more on our Knowledge Base or by heading to each exam’s homepage.        
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Finding certified practitioners</:toggle>
      <:content>
        HashiCorp publishes all earned badges to a publicly searchable directory on Credly. Here, you can filter and find people who hold HashiCorp Cloud Engineer certifications. Learn how to opt-out of this service in our Knowledgebase.
      </:content>
    </A.Item>
  </Hds::Accordion>

ariaLabel

The ariaLabel value is applied to the HTML button which controls visibility of the content block. The text does not display in the UI. The default value is "Toggle display" but you can set a custom value useful for translated text for example.

Elemento uno
  <Hds::Accordion as |A|>
    <A.Item @ariaLabel="Mostrar u ocultar">
      <:toggle>Elemento uno</:toggle>
      <:content>
        Contenido adicional para el elemento uno
      </:content>
    </A.Item>
  </Hds::Accordion>

titleTag

The @titleTag argument changes the HTML element that wraps the title block of each Accordion::Item. When organizing the content on a webpage, the heading levels should reflect the structure of the page. For example, if an Accordion is within a subsection of the page below a heading level 2, the value should be "h3".

Examination period

Exam experience

Requirements for attending an exam

Your badge and certificate

  <div class="doc-accordion-demo-heading">
    <Hds::Text::Display @tag="h2" @size="300">Examination period</Hds::Text::Display>
  </div>
  <Hds::Accordion @titleTag="h3" as |A|>
    <A.Item>
      <:toggle>Exam experience</:toggle>
      <:content>
        All certification exams are taken online with a live proctor, accommodating all locations and time zones. Online proctoring provides the same benefits of a physical test center while being more accessible to exam-takers. The live proctor verifies your identity, walks you through rules and procedures, and watches you take the exam. Learn more ways to prepare for an online proctored exam in our Knowledgebase.
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Requirements for attending an exam</:toggle>
      <:content>
        Before you register for an exam, review the Exam-taker Handbook to learn the requirements and policies for taking exams. It is your responsibility to know and abide by our program rules to successfully enter your exam appointment, failure to do so may result in forfeiture of appointment fees.        
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Your badge and certificate</:toggle>
      <:content>
        HashiCorp has partnered with Credly to offer you a digital badge and downloadable certificate upon passing a certification exam. There is no fee for this service and acceptance is up to you. Digital badges can be used in email signatures or digital resumes, and on social media sites such as LinkedIn, Facebook, and Twitter. Badges link back to a real-time verification feature that describes your qualifications.
      </:content>
    </A.Item>
  </Hds::Accordion>

The default @titleTag is "div" because the correct value is dependent on the individual page. We strongly encourage consumers to update the @titleTag to meet WCAG Success Criterion 1.3.1 Info and Relationships as the visual experience should match what is presented to the user with assistive technology.

isOpen

Set isOpen to true on an Accordion::Item to display its associated content on page load instead of initially hiding it.

Item one
Additional content for item one which is displayed on page load
Item two
  <Hds::Accordion as |A|>
    <A.Item @isOpen={{true}}>
      <:toggle>Item one</:toggle>
      <:content>
        Additional content for item one which is displayed on page load
      </:content>
    </A.Item>
    <A.Item>
      <:toggle>Item two</:toggle>
      <:content>
        Additional content for item two which is hidden on page load
      </:content>
    </A.Item>
  </Hds::Accordion>

isStatic

Set isStatic to true on an Accordion::Item to remove the ability to interact with the toggle.

Item one
Item two
  <Hds::Accordion as |A|>
    <A.Item>
      <:toggle>Item one</:toggle>
      <:content>
        Additional content for item one
      </:content>
    </A.Item>
    <A.Item @isStatic={{true}}>
      <:toggle>Item two</:toggle>
      <:content>
        Additional content for item two
      </:content>
    </A.Item>
  </Hds::Accordion>

containsInteractive

By default, the containsInteractive property of the Accordion::Item is set to false, meaning that the entire Accordion::Item toggle block can be clicked to hide and show the associated content. If set to true, only the chevron button of the Accordion::Item is clickable vs. the entire block. This allows you to add other interactive content inside the toggle block if desired.

Peering connection log results Details
<Hds::Accordion as |A|>
  <A.Item @containsInteractive={{true}}>
    <:toggle>
      <div class="doc-accordion-item-toggle-content-flex-layout">
        <Hds::Alert @type="compact" @color="success" as |A|>
          <A.Title>Title</A.Title>
          <A.Description>Plan finished <small>22 days ago</small></A.Description>
        </Hds::Alert>
        <Hds::Button @text="Details" @color="secondary" @size="small" />
      </div>
    </:toggle>
    <:content>
      Additional content for item one
    </:content>
  </A.Item>
  <A.Item @containsInteractive={{true}}>
    <:toggle>
      <div class="doc-accordion-item-toggle-content-flex-layout">
        <span>Peering connection log results</span>
        <Hds::Link::Standalone @icon="external-link" @iconPosition="trailing" @text="Details" @href="https://www.hashicorp.com/" />
      </div>
    </:toggle>
    <:content>
      Additional content for item two
    </:content>
  </A.Item>
</Hds::Accordion>

Component API

Accordion

The Accordion component serves as a wrapper to group one or more Accordion::Item components.

<[A].Item> yielded component
Accordion::Item yielded as contextual component (see below).
size enum
  • small
  • medium (default)
  • large
type enum
  • card (default)
  • flush
forceState enum
  • open
  • close
Controls the state of all items within a group. Can be used to expand or collapse all items at once.
titleTag enum
  • div (default)
  • h1
  • h2
  • h3
  • h4
  • h5
  • h6
The HTML tag that wraps the content of each Accordion Item "toggle" block.
…attributes
This component supports use of ...attributes.

Contextual components

[A].Item

The Accordion::Item component, yielded as contextual component.

<:toggle> named block
A named block that works as a “toggle” for the Accordion::Item.
yield
Elements passed as children are yielded as inner content of the "toggle" block.
<:content> named block
A named block for the content that is shown/hidden upon toggling.
yield
Elements passed as children are yielded as inner content of the "content" block.
[C].close function
A function to programmatically close the Accordion::Item.
ariaLabel string
  • "Toggle display" (default)
Accepts a localized string. The ariaLabel value is applied to the HTML button which controls visibility of the content block content.
isOpen boolean
  • false (default)
Toggles the visibility of the content. To display content on page load, set the value to true.
isStatic boolean
  • false (default)
Removes the ability to interact with the toggle and hides the chevron element when set to true.
containsInteractive boolean
  • false (default)
Controls whether the entire toggle block is interactive for toggling the content display or whether only the chevron button itself is interactive which allows for adding other interactive content in the toggle area.
forceState enum
  • open
  • close
Controls the state of an Accordion::Item after the initial render by overriding its current state.
onClickToggle function
Callback function invoked when the toggle is clicked.
…attributes
This component supports use of ...attributes.

Anatomy

Anatomy of accordion

Element Usage
Item Required, at least one
Toggle Required
Content Required

States

Default

Accordion states

Is open

Accordion states when is open

Contains interactive

Accordion states with nested interactive elements

Is open

Accordion states with nested interactive elements

Conformance rating

Conformant

When used as recommended, there should not be any WCAG conformance issues with this component.

Keyboard navigation

Tab

Focus on a toggle.

Keyboard accordion navigation example

Spacebar
Enter

Expand container to display hidden content.

Keyboard accordion navigation example

Tab

Move to the first interactive element within the content area.

Keyboard accordion navigation example

When containsInteractive, the focus will first move to the toggle button, then to the nested interactive elements in the toggle area.

Keyboard accordion navigation example

Applicable WCAG Success Criteria

This section is for reference only. This component intends to conform to the following WCAG Success Criteria:

  • 1.1.1 Non-text Content (Level A):
    All non-text content that is presented to the user has a text alternative that serves the equivalent purpose.
  • 1.3.1 Info and Relationships (Level A):
    Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
  • 1.3.2 Meaningful Sequence (Level A):
    When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined.
  • 1.4.1 Use of Color (Level A):
    Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.
  • 1.4.10 Reflow (Level AA):
    Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions.
  • 1.4.11 Non-text Contrast (Level AA):
    The visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s): user interface components; graphical objects.
  • 1.4.12 Text Spacing (Level AA):
    No loss of content or functionality occurs by setting all of the following and by changing no other style property: line height set to 1.5; spacing following paragraphs set to at least 2x the font size; letter-spacing set at least 0.12x of the font size, word spacing set to at least 0.16 times the font size.
  • 1.4.13 Content on Hover or Focus (Level AA):
    Where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, the following are true: dismissible, hoverable, persistent (see link).
  • 1.4.3 Minimum Contrast (Level AA):
    The visual presentation of text and images of text has a contrast ratio of at least 4.5:1
  • 1.4.4 Resize Text (Level AA):
    Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.
  • 2.1.1 Keyboard (Level A):
    All functionality of the content is operable through a keyboard interface.
  • 2.1.2 No Keyboard Trap (Level A):
    If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface.
  • 2.4.3 Focus Order (Level A):
    If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability.
  • 2.4.6 Headings and Labels (Level AA):
    Headings and labels describe topic or purpose.
  • 2.4.7 Focus Visible (Level AA):
    Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.
  • 2.5.3 Label in Name (Level A):
    For user interface components with labels that include text or images of text, the name contains the text that is presented visually.
  • 3.2.1 On Focus (Level A):
    When any user interface component receives focus, it does not initiate a change of context.
  • 3.2.4 Consistent Identification (Level AA):
    Components that have the same functionality within a set of Web pages are identified consistently.
  • 4.1.2 Name, Role, Value (Level A):
    For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.

Support

If any accessibility issues have been found within this component, let us know by submitting an issue.


Related