Collapsible Sections
NOTE:
- New to accessibility or uncertain of requirements, it will be helpful to review all sections below.
- Already familiar with requirements, skip to the “Working Example” section for sample HTML, CSS and JavaScript (when needed), along with a working demo.
- A collapsible section is a widget that can show / hide content.
- It comprises two components: a button and the content that becomes available on expanding that button.
- Generally, a plus/minus icon is used to indicate a collapsible section.
-
This icon SHOULD NOT be defined through CSS
background-image
property. - The color contrast ratio requirement of 4.5:1 MUST be met considering standard text size of the button text and its content.
- The color contrast requirement of 3:1 ratio MUST be met with the adjacent color for plus/minus icon.
- The contrast requirement of 3:1 ratio MUST be met with the adjacent colors for the custom focus indicator of the button of collapsible section.
- A distinct visual focus MUST be visible for the buttons.
-
The content MUST be
hidden
using native HTML hidden attribute or the CSSdisplay: none
property when the button is in collapsed state. -
In expanded state the hidden attribute SHOULD get removed and CSS
display: none
property SHOULD update todisplay: block
.
Note: A combination of native HTML hidden attribute and CSS display property is recommended for robust support across different environments.
The button can be implemented using the following approaches:
HTML
- The button SHOULD be defined using native HTML
<button>
element. -
Appropriate heading level SHOULD be provided for the button using native HTML
heading elements like
<h2> - <h6>
.- The button MUST be nested within the heading element.
- The heading element MUST NOT be nested within the button as it will suppress the heading semantics from assistive technology like screen reader.
-
The
aria-expanded
attribute MUST be provided by default for defining the expanded/collapsed state of the button.- The default value of this attribute SHOULD be set to false as the button is in collapsed state.
- The value SHOULD be updated to true when the button is in expanded state.
-
The
aria-controls
attribute CAN be defined for the button. Its value refers to the id value of the container of the expanded content.
ARIA
Though ARIA CAN be used as an alternative, it is advisable to use correct semantic HTML element since native elements have built-in keyboard accessibility, roles and states.
-
The button SHOULD be defined using
role="button"
for the parent neutral container such as<div>
element. -
A
tabindex="0"
attribute MUST be provided for the neutral container such as<div>
element havingrole="button"
.- Appropriate JavaScript event handlers MUST be used to make the button accessible by keyboard and mouse.
-
The
aria-expanded
attribute MUST be provided for defining the expanded/collapsed state of the button. -
The
aria-controls
attribute CAN be provided for associating the button to its respective content. It references the id attribute value defined for the<div>
container containing the collapsible section.
Focus and Keyboard management:
- When focus is on the button, pressing Enter/ Space shows/hides the collapsible section.
- Pressing Tab key moves focus to the next button/ interactive element.
- The focus SHOULD NOT move on the expanded content when the button is activated.
-
The content SHOULD be defined in a neutral container such as
<div>
element. -
An id attribute CAN be provided to the
<div>
container to reference witharia-controls
attribute of the respective buttons. -
The
role="region"
andaria-labelledby
attribute CAN be provided to the<div>
element of the content. Thearia-labelledby
attribute value refers to the id attribute of the button.
For example,
<!-- Triggering button code in collapsed state -->
<!--suppress XmlDuplicatedId, XmlDuplicatedId -->lDuplicatedId -->lDuplicatedId -->
<h2>
<button class="collapsible" aria-controls="content1" aria-expanded="false" id="section_1">
What's Pearson+?
<svg viewBox="0 0 10 10" aria-hidden="true" focusable="false">
<rect class="vert" height="8" width="2" y="1" x="4" />
<rect height="2" width="8" y="4" x="1" />
</svg>
</button>
</h2>
<!-- Triggering button code in expanded state -->
<h2>
<button class="collapsible active" aria-controls="content1" aria-expanded="true" id="section_1">
What's Pearson+?
<svg viewBox="0 0 10 10" aria-hidden="true" focusable="false">
<rect class="vert" height="8" width="2" y="1" x="4"></rect>
<rect height="2" width="8" y="4" x="1"></rect>
</svg>
</button>
</h2>
<!-- Collapsible section code in collapsed state -->
<div id="content1" class="content hidden" role="region" aria-labelledby="section_1" aria-hidden="true">
<p>
Introducing Pearson+. Reimagined learning, designed for you. Choose from one
eTextbook or over 1,500 eTextbooks and study tools, all in one place, for
one low monthly subscription. A new way to buy books that fits your budget.
Make the most of your study time with offline access, enhanced search, notes
and flashcards — to get organized, get the work done quicker and get results.
Plus, with the app, put textbooks in your pocket and learn wherever. It's
time to upgrade the textbook and simplify learning, so you can have time to
live too.
</p>
</div>
<!-- Collapsible section code in expanded state -->
<div id="content1" class="content hidden" role="region" aria-labelledby="section_1" aria-hidden="false">
<p>
Introducing Pearson+. Reimagined learning, designed for you. Choose from one
eTextbook or over 1,500 eTextbooks and study tools, all in one place, for
one low monthly subscription. A new way to buy books that fits your budget.
Make the most of your study time with offline access, enhanced search, notes
and flashcards — to get organized, get the work done quicker and get results.
Plus, with the app, put textbooks in your pocket and learn wherever. It's
time to upgrade the textbook and simplify learning, so you can have time to
live too.
</p>
</div>
A well-defined collapsible section benefits majorly the below users.
- People with cognitive disabilities
- People using speech input
- People with limited dexterity
- People using keyboard only
- People using screen readers
<div class="accordion-panel">
<h2>
<button class="collapsible" aria-controls="content1" aria-expanded="false" id="section_1">What's Pearson+?
<svg viewBox="0 0 10 10" aria-hidden="true" focusable="false">
<rect class="vert" height="8" width="2" y="1" x="4" />
<rect height="2" width="8" y="4" x="1" />
</svg>
</button>
</h2>
<div id="content1" class="accordion-content hidden" role="region" aria-labelledby="section_1" aria-hidden="true">
<p>
Introducing Pearson+. Reimagined learning, designed for you. Choose from
one eTextbook or over 1,500 eTextbooks and study tools, all in one place,
for one low monthly subscription. A new way to buy books that fits your
budget. Make the most of your study time with offline access, enhanced
search, notes and flashcards — to get organized, get the work done
quicker and get results. Plus, with the app, put textbooks in your pocket
and learn wherever. It's time to upgrade the textbook and simplify
learning, so you can have time to live too.
</p>
</div>
</div>
<div class="accordion-panel">
<h2>
<button class="collapsible" aria-controls="content2" aria-expanded="false" id="section_2">What's an eTextbook?
<svg viewBox="0 0 10 10" aria-hidden="true" focusable="false">
<rect class="vert" height="8" width="2" y="1" x="4" />
<rect height="2" width="8" y="4" x="1" />
</svg>
</button>
</h2>
<div id="content2" class="accordion-content hidden" role="region" aria-labelledby="section_2" aria-hidden="true">
<p>
eTextbook is an easy-to-use digital textbook available from Pearson+. Make
it your own by adding notes and highlights. Download the Pearson+ mobile
app to learn on the go, even offline. Listen on the go with our new
audiobook feature, available for most titles.
</p>
</div>
</div>
<div class="accordion-panel">
<h2>
<button class="collapsible" aria-controls="content3" aria-expanded="false" id="section_3">How does the 4-month subscription term work?
<svg viewBox="0 0 10 10" aria-hidden="true" focusable="false">
<rect class="vert" height="8" width="2" y="1" x="4" />
<rect height="2" width="8" y="4" x="1" />
</svg>
</button>
</h2>
<div id="content3" class="accordion-content hidden" role="region" aria-labelledby="section_3" aria-hidden="true">
<p>
When you choose a plan, you're signing up for a 4-month 'term'. You can opt
to make a one-time payment for the initial 4-month term or pay monthly. If
you opt for monthly payments, we will charge your payment method each month
until your 4-month term has ended. You can turn on auto-renew in My account
at any time to continue your subscription before your 4-month term has ended.
</p>
</div>
</div>
<div class="accordion-panel">
<h2>
<button class="collapsible" aria-controls="content4" aria-expanded="false" id="section_4">How does auto-renew work?
<svg viewBox="0 0 10 10" aria-hidden="true" focusable="false">
<rect class="vert" height="8" width="2" y="1" x="4" />
<rect height="2" width="8" y="4" x="1" />
</svg>
</button>
</h2>
<div id="content4" class="accordion-content hidden" role="region" aria-labelledby="section_4" aria-hidden="true">
<p>
When you purchase a Pearson+ subscription, it will last 4 months. Before
your initial 4-month term ends, you can extend your subscription by turning
auto-renew on in My account. If you turn auto-renew on, we’ll automatically
renew your subscription and charge you every month until you turn off
auto-renew. If you made a one-time payment for your initial 4-month term,
you’ll now pay monthly. To avoid the next payment charge, make sure you turn
auto-renewal off 1 day before the auto-renewal date. You can subscribe again
after auto-renew has been turned off by purchasing another Pearson+
subscription. We use your credit card to renew your subscription
automatically. To make sure your learning is uninterrupted, please check your
card details before your first monthly payment.
</p>
</div>
</div>
.collapsible {
color: rgb(0, 0, 0);
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.content {
padding: 0 18px;
max-height: 15em;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
[aria-expanded="true"] .vert {
display: none;
}
button:focus svg {
outline: 2px solid;
}
[aria-expanded] rect {
fill: currentColor;
}
button svg {
height: 1em;
margin-left: 0.5em;
float: right;
}
h2 {
margin-bottom: 0;
}
.accordion-panel {
box-shadow: 0 2px 4px rgba(0,0,0,0.25);
background-color: #fefefe;
border-radius: 4px;
transition: box-shadow .125s ease-in-out;
}
.accordion-panel:hover {
box-shadow: 0 0 25px rgba(0,0,0,0.15);
}
.active {
background-color: #007a9c;
color: #fff;
}
.hidden {
display: none;
}
let sections = document.querySelectorAll('.collapsible');
let content;
sections.forEach(item => {
item.addEventListener('click', function() {
/* Get the current state of the button when it is clicked */
let currentState = item.classList.contains('active');
/*
Close all section before determining if a section should be displayed
If you do not want any open sections to automatically close when another section is activated
comment out the forEach loop
*/
sections.forEach(item => {
item.setAttribute('aria-expanded', 'false');
const controls = item.getAttribute('aria-controls');
document.getElementById(item.getAttribute('aria-controls')).classList.add('hidden');
item.classList.remove('active');
document.getElementById(item.getAttribute('aria-controls')).setAttribute('aria-hidden', 'true');
});
/* If the currentState of the button was not active, then make it active */
if (!currentState) {
item.setAttribute("aria-expanded",'true')
item.classList.add('active');
}
/* Set the content section of the accordion to display if the button is active */
const controlsId = item.getAttribute('aria-controls');
content = document.getElementById(controlsId);
const isExpanded = item.getAttribute('aria-expanded') === 'true';
if (!isExpanded) {
content.classList.add('hidden');
content.setAttribute('aria-hidden', 'true')
} else {
content.classList.remove('hidden');
content.setAttribute('aria-hidden', 'false')
}
});
});
Introducing Pearson+. Reimagined learning, designed for you. Choose from one eTextbook or over 1,500 eTextbooks and study tools, all in one place, for one low monthly subscription. A new way to buy books that fits your budget. Make the most of your study time with offline access, enhanced search, notes and flashcards — to get organized, get the work done quicker and get results. Plus, with the app, put textbooks in your pocket and learn wherever. It's time to upgrade the textbook and simplify learning, so you can have time to live too.
eTextbook is an easy-to-use digital textbook available from Pearson+. Make it your own by adding notes and highlights. Download the Pearson+ mobile app to learn on the go, even offline. Listen on the go with our new audiobook feature, available for most titles.
When you choose a plan, you're signing up for a 4-month 'term'. You can opt to make a one-time payment for the initial 4-month term or pay monthly. If you opt for monthly payments, we will charge your payment method each month until your 4-month term has ended. You can turn on auto-renew in My account at any time to continue your subscription before your 4-month term has ended.
When you purchase a Pearson+ subscription, it will last 4 months. Before your initial 4-month term ends, you can extend your subscription by turning auto-renew on in My account. If you turn auto-renew on, we’ll automatically renew your subscription and charge you every month until you turn off auto-renew. If you made a one-time payment for your initial 4-month term, you’ll now pay monthly. To avoid the next payment charge, make sure you turn auto-renewal off 1 day before the auto-renewal date. You can subscribe again after auto-renew has been turned off by purchasing another Pearson+ subscription. We use your credit card to renew your subscription automatically. To make sure your learning is uninterrupted, please check your card details before your first monthly payment.