Accordion
An accordion is comprised of multiple Collapsible components that open and close when their summary (heading) is clicked, hiding or revealing content.
Playground
<Accordion><BasicCollapsible collapsibleId="coll-one" heading="Summary 1">Content 1</BasicCollapsible><BasicCollapsible collapsibleId="coll-two" heading="Summary 2">Content 2</BasicCollapsible></Accordion>
<div class="accordion"><div class="collapsible"><h3 class="collapsible-summary"><!-- does not have to be an <h*> tag --><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentA1">Summary 1</button></h3><div class="collapsible-content" id="exampleAccordionContentA1">Content 1</div></div><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentA2">Summary 2</button></h3><div class="collapsible-content" id="exampleAccordionContentA2">Content 2</div></div></div>
An Accordion consists of one or more Collapsible components. In React, a Collapsible
must have a collapsibleId
when used inside of an Accordion
. This info is necessary so that the Accordion
can control the state of the Collapsible
.
Single vs Multiple
Multiple collapsibles can be open at the same time.
In React, the default is to allow multiple collapsibles to be open at the same time. If you want to ensure that there's only one expanded collapsible at a time, you can add the
single
option.The vanilla Visage accordion defaults to allowing one collapsible to be open at a given time; to allow multiple nodes open at once, add CSS class
"accordion-multiple"
to the element that has classaccordion
on it.
<>{/* multiple */}<Accordion>...</Accordion>{/* single */}<Accordion single>...</Accordion></>
<!-- multiple --><div class="accordion accordion-multiple">...</div><!-- single --><div class="accordion">...</div>
Large
Accordions can be made to use the "large" option. This is useful for nested accordions, where we usually want the outside accordion to be large, but the inner ones to be regular size:
<Accordion sizeVariant="large"><BasicCollapsible heading="Summary 1" collapsibleId="one"><Accordion><BasicCollapsible heading="Summary 1A" collapsibleId="oneA">Content for 1A</BasicCollapsible><BasicCollapsible heading="Summary 1B" collapsibleId="oneB">Content for 1B</BasicCollapsible></Accordion></BasicCollapsible><BasicCollapsible heading="Summary 2" collapsibleId="two"><Accordion><BasicCollapsible heading="Summary 2A" collapsibleId="twoA">Content for 2A</BasicCollapsible><BasicCollapsible heading="Summary 2B" collapsibleId="twoB">Content for 2B</BasicCollapsible></Accordion></BasicCollapsible></Accordion>
<div class="accordion accordion-large"><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentTOuter1">Summary 1</button></h3><div class="collapsible-content" id="exampleAccordionContentTOuter1"><div class="accordion"><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentTInner1A">Summary 1A</button></h3><div class="collapsible-content" id="exampleAccordionContentTInner1A">Content for 1A</div></div><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentTInner1B">Summary 2</button></h3><div class="collapsible-content" id="exampleAccordionContentTInner1B">Content for 1B</div></div></div></div></div><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentTOuter2">Summary 2</button></h3><div class="collapsible-content" id="exampleAccordionContentTOuter2"><div class="accordion"><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentTInner2A">Summary 2A</button></h3><div class="collapsible-content" id="exampleAccordionContentTInner2A">Content for 2A</div></div><div class="collapsible"><h3 class="collapsible-summary"><buttonclass="collapsible-summary-button"aria-expanded="false"aria-controls="exampleAccordionContentTInner2B">Summary 2</button></h3><div class="collapsible-content" id="exampleAccordionContentTInner2B">Content for 2B</div></div></div></div></div></div>
"full-bleed"
The "full-bleed" option on an Accordion (or an individual Collapsible) removes any left- and right-hand padding around the contents.
<Accordion fullBleed><BasicCollapsible collapsibleId="coll-one" heading="Summary 1">Content 1 using full bleed</BasicCollapsible><BasicCollapsible collapsibleId="coll-two" heading="Summary 2">Content 2 using full bleed. This collapsible's content will go all the wayout to the right edge. This collapsible's content will go all the way out tothe right edge. This collapsible's content will go all the way out to theright edge. This collapsible's content will go all the way out to the rightedge.</BasicCollapsible></Accordion>
"Color Swatches" skin
The "color swatches" skin for the Accordion is use to wrap a set of Color Swatches when a high number of swatches would make the content too tall.
The summary button shows the total number of available swatches.
<GridContainer><Row><Column span={6}><Accordion skin="color-swatches"><Collapsible><CollapsibleSummary><CollapsibleSummaryButton>10<Box as="span" visuallyHidden>{' '}color choices</Box></CollapsibleSummaryButton></CollapsibleSummary><CollapsibleContent><StandardTileSwatches><SelectionSet data-testid="set1" defaultSelectedValue="indigo"><ColorSwatches><SelectionSetInput value="red/black"><SelectionSetLabel><ColorSwatchprimaryColor="red"secondaryColor="black"title="color red/black"/></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="indigo"><SelectionSetLabel><ColorSwatch primaryColor="indigo" title="color indigo" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="green"><SelectionSetLabel><ColorSwatch primaryColor="green" title="color green" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="gold"><SelectionSetLabel><ColorSwatch primaryColor="gold" title="color gold" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="blue"><SelectionSetLabel><ColorSwatch primaryColor="blue" title="color blue" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="orange"><SelectionSetLabel><ColorSwatch primaryColor="orange" title="color orange" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="pink"><SelectionSetLabel><ColorSwatch primaryColor="pink" title="color pink" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput value="brown"><SelectionSetLabel><ColorSwatch primaryColor="brown" title="color brown" /></SelectionSetLabel></SelectionSetInput><SelectionSetInput disabled value="limegreen"><SelectionSetLabel><ColorSwatchprimaryColor="limegreen"title="color lime green"/></SelectionSetLabel></SelectionSetInput><SelectionSetInput disabled value="darkmagenta"><SelectionSetLabel><ColorSwatchprimaryColor="darkmagenta"title="color dark magenta"/></SelectionSetLabel></SelectionSetInput></ColorSwatches></SelectionSet></StandardTileSwatches></CollapsibleContent></Collapsible></Accordion></Column></Row></GridContainer>
Accordions as lists
If the Accordion
is semantically a list (e.g. a list of steps), then it needs the appropriate HTML tags:
In React, add the
purpose="list"
prop to theAccordion
.In vanilla JS, use
<ul>
and<li>
tags as appropriate in the HTML, such as using<ul>
for the Accordion, and<li>
on each Collapsible inside it.
Steps
The Accordion supports a skin called steps
that's used to create a very compact step-by-step experience. If you're looking to create an Accordion-based step-flow, check out our tutorial on creating a step flow with Accordion. (In React, use StepCollapsible
inside the Accordion instead of BasicCollapsible
when creating this experience.)
Controlled
In React, if you want to take control over the state of the Accordion
, that's supported too. Note that this is usually only necessary if you want to be able to read/write the Accordion
's state from another component, so it should be uncommon.
When a Collapsible
is on its own, we control it via its expanded
prop, but when used inside of an Accordion
, you should define the expandedCollapsibles
prop on the Accordion
itself. expandedCollapsibles
is a map of collapsibleId
s to a boolean
for whether or not the Collapsible
should be expanded.
If
expandedCollapsibles
is provided, thesingle
prop will be ignored andexpandedCollapsibles
will be treated as the source of truth.
Provide the onRequestExpandedChange
prop on the Accordion
in order to be notified when a Collapsible
wants to expand or collapse. The onRequestExpandedChange
handler will be invoked with two args: the collapsibleId
for the Collapsible
that wants to change its state, and a boolean
for whether or not the Collapsible
wants to be expanded.
() => {const [expandedCollapsibles, setExpandedCollapsibles] = React.useState({'coll-one': false,'coll-two': true,})return (<AccordionexpandedCollapsibles={expandedCollapsibles}onRequestExpandedChange={(collapsibleId, expanded) => {setExpandedCollapsibles(prevValue => ({...prevValue,[collapsibleId]: expanded,}))// or if you want to emulate "single" behavior// setExpandedCollapsibles({ [collapsibleId]: expanded })}}><BasicCollapsible collapsibleId="coll-one" heading="Heading 1">Content 1</BasicCollapsible><BasicCollapsible collapsibleId="coll-two" heading="Heading 2">Content 2</BasicCollapsible></Accordion>)}
Props
Accordion
Prop | Type | Default | Description |
---|---|---|---|
skin | "standard" | "steps" | "peek" | "color-swatches" | "standard" | The visual style of the Accordion |
sizeVariant | "standard" | "large" | false | The size of the accordion |
bounded | boolean | false | Whether or not the Accordion should have a border |
fullBleed | boolean | Whether or not the Accordion contents are full-bleed | |
single | boolean | false | Whether or not the Accordion should only allow a single Collapsible to be open at a time |
purpose | "list" | The semantic purpose of the Accordion It is used in order to render the appropriate semantic markup e.g. if purpose is 'steps-list' the Accordion will render an <ol> element by default | |
expandedCollapsibles | ExpandedCollapsibles | A map of collapsibleId to expanded-status which represents the desired state of the Accordion | |
onRequestExpandedChange | (collapsibleId: string, expanded: boolean) => void | A callback fired when a Collapsible wants to change its state It is passed the collapsibleId and a boolean for whether or not the Collapsible wants to be expanded | |
defaultExpandedCollapsibles | ExpandedCollapsibles | Initial expanded-states for the Collapsibles This is ignored if expandedCollapsibles is provided |
All other props are forwarded to the element specified in thecomponent
prop(default: <div/>
)
Related
Guidelines
Designer Guidelines
It is important that each summary be written to clearly indicate what is in its contents. Make sure the text is unambiguous to the user.
Content within a closed accordion is not visible to search engines, since search engines can't see any information that requires user interaction to view. For "see more info" collapsibles this might be okay, but for lengthy accordions, make sure at least one accordion is open by default.
The "peek" skin shows a small amount of the content while the accordion is closed. It is intended for SEO copy and similar blocks of text where we want to entice the user into opening the accordion. This skin should only be used for accordions with a single collapsible.
Developer Guidelines
When using the vanilla JS API, a collapsible that should default to open needs both an
aria-expanded="true"
onto thecollapsible-summary-button
element and the classcollapsible-content-open
on the associatedcollapsible-content
element. (The React component takes care of this for you.)Using the "rich" option on the summary element allows you to customize the summary typography by putting typographic styles onto sub-elements inside the summary. Those sub-elements will be arranged in a single horizontal line, aligned to the left. Adding the "align right" option to the last sub-element will make that sub-element align to the right edge.
Accessibility Guidelines
The React component takes care of these two attributes for you, but if you are using the vanilla API, you will need to set these for every collapsible-summary-button
:
an
aria-expanded
attribute set totrue
orfalse
, depending on whether the accordion is open or closed.an
aria-controls
attribute whose value is the id of thecollapsible-content
section it controls.
SEO Considerations
Googlebot is able to crawl and get data within accordions as long as that data is part of the page's source HTML. If the content is added dynamically through JavaScript, the developer must validate with the Organic Search team that Googlebot can crawl the content. Important content should not go into an accordion, since Googlebot considers content within an accordion as secondary (or less important), as it requires one more click from the user.