Accordion
The accordion component lets users show and hide sections of content on a page.
When to use
Only use an accordion if there's evidence it's helpful for users to:
- see an overview of multiple, related sections of content
- show and hide those sections as needed
- compare information that might otherwise be on different pages
- find only the part of a long page that are relevant to them
Accordions can work well for people who use a service regularly. For example, those already familiar with most of the content in an accordion and only need to refer to individual sections.
When not to use
Do not use an accordion for short content that can be set out on the page. An accordion must only be used when content needs to be divided into 4 sections or more.
Do not use accordions for content which is essential for all users. Accordions hide content and not everyone will notice them or understand how they work.
It might be better to:
- simplify and reduce the amount of content
- split the content across multiple pages
- keep the content on a single page, separated by headings
- use a list of links to let users navigate quickly to specific sections of content
Do not put accordions within accordions, as it will make content difficult to find.
Do not use the accordion component if the amount of content inside will make the page slow to load.
Use clear labels
Accordions hide content, so the labels need to be clear and as concise as possible.
Standard
The 'Show all' button allows users to show all content in each accordion. The button changes to "Hide all" when all the content is showing, which allows the user to hide all the collapsible content.
- HTML5
- JavaScript
<section class="accordion-block">
<button
id="toggle-all__button-show-all"
class="accordion_all-button"
onclick="toggleAllItems()"
>
<p>Show all <i class="bcc-font_down"></i></p>
</button>
<div class="accordion">
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all"
aria-controls="accordion-content-zlqjpn"
>
Social inclusion
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-zlqjpn">
The person cannot recognise facial expressions or detail within objects
at approximately 6 metres. This significantly impacts upon social
inclusion.
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all"
aria-controls="accordion-content-j1txa5"
>
Physical safety
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-j1txa5">
Is physically safe in the educational setting accessing all of the
physical environment independently.
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all"
aria-controls="accordion-content-bo39t"
>
Wellbeing and identity
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-bo39t">
Reports to feeling happy in the educational setting. Their emotional
wellbeing is good.
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all"
aria-controls="accordion-content-n8y8ug"
>
Understanding needs
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-n8y8ug">
Has no visual difficulties or impairment.
</div>
</div>
</div>
</section>
function updateToggleAllButton(button) {
const accordionItems = document.querySelectorAll(
'.accordion-button[data-random-id="show-all"]'
);
let allExpanded = true;
for (var i = 0; i < accordionItems.length; i++) {
const item = accordionItems[i];
const isExpanded = item.getAttribute("aria-expanded") === "true";
if (!isExpanded) {
allExpanded = false;
}
}
if (button) {
button.innerHTML = allExpanded
? '<p>Hide all <i class="bcc-font_up"></i></p>'
: '<p>Show all <i class="bcc-font_down"></i></p>';
}
}
function toggleAllItems() {
const accordionItems = document.querySelectorAll(
'.accordion-button[data-random-id="show-all"]'
);
const allExpanded = Array.from(accordionItems).every(
(item) => item.getAttribute("aria-expanded") === "true"
);
for (var i = 0; i < accordionItems.length; i++) {
const item = accordionItems[i];
const target = item.closest(".accordion-header").nextElementSibling;
const icon = item.querySelector("i");
if (allExpanded) {
icon.className = "bcc-font_down";
} else {
icon.className = "bcc-font_up";
}
item.setAttribute("aria-expanded", !allExpanded);
target.hidden = allExpanded;
}
const topButton = document.querySelector("#toggle-all__button-show-all");
updateToggleAllButton(topButton);
}
window.onload = function () {
const elements = document.querySelectorAll(
'.accordion h2.accordion-heading[data-random-id="show-all"]'
);
for (var i = 0; i < elements.length; i++) {
const element = elements[i];
const btn = element.querySelector("button");
const target = element.closest(".accordion-header").nextElementSibling;
const contentID = `accordion-content-${i}`;
target.id = contentID;
btn.setAttribute("aria-controls", contentID);
btn.onclick = function (e) {
e.preventDefault;
let expanded = btn.getAttribute("aria-expanded") === "true";
btn.setAttribute("aria-expanded", !expanded);
target.hidden = expanded;
const icon = btn.querySelector("i");
if (!expanded) {
target.focus();
icon.className = "bcc-font_up";
} else {
icon.className = "bcc-font_down";
}
const topButton = document.querySelector("#toggle-all__button-show-all");
updateToggleAllButton(topButton);
};
}
};
With summary text
Write your accordion labels so that a user can understand what's inside, without having to open the accordion.
However, if you need to provide more information, you can add summary text. You should make the summary text as clear and concise as possible.
Challenges with recognition
Independently safe
Positive emotional wellbeing
No visual impairment
- HTML5
- JavaScript
<section class="accordion-block">
<button
id="toggle-all__button-show-all-with-summary"
class="accordion_all-button"
onclick="toggleAllItems()"
>
<p>Show all <i class="bcc-font_down"></i></p>
</button>
<div class="accordion">
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-with-summary">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all-with-summary"
aria-controls="accordion-content-zlqjpn"
>
Social inclusion
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<h2 class="accordion-summary">Challenges with recognition</h2>
<div hidden="" tabindex="-1" id="accordion-content-zlqjpn">
The person cannot recognise facial expressions or detail within objects
at approximately 6 metres. This significantly impacts upon social
inclusion.
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-with-summary">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all-with-summary"
aria-controls="accordion-content-j1txa5"
>
Physical safety
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<h2 class="accordion-summary">Independently safe</h2>
<div hidden="" tabindex="-1" id="accordion-content-j1txa5">
Is physically safe in the educational setting accessing all of the
physical environment independently.
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-with-summary">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all-with-summary"
aria-controls="accordion-content-bo39t"
>
Wellbeing and identity
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<h2 class="accordion-summary">Positive emotional wellbeing</h2>
<div hidden="" tabindex="-1" id="accordion-content-bo39t">
Reports to feeling happy in the educational setting. Their emotional
wellbeing is good.
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-with-summary">
<button
type="button"
class="accordion-button"
aria-expanded="false"
data-random-id="show-all-with-summary"
aria-controls="accordion-content-n8y8ug"
>
Understanding needs
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<h2 class="accordion-summary">No visual impairment</h2>
<div hidden="" tabindex="-1" id="accordion-content-n8y8ug">
Has no visual difficulties or impairment.
</div>
</div>
</div>
</section>
function updateToggleAllButton(button) {
const accordionItems = document.querySelectorAll(
'.accordion-button[data-random-id="show-all-with-summary"]'
);
let allExpanded = true;
for (var i = 0; i < accordionItems.length; i++) {
const item = accordionItems[i];
const isExpanded = item.getAttribute("aria-expanded") === "true";
if (!isExpanded) {
allExpanded = false;
}
}
if (button) {
button.innerHTML = allExpanded
? '<p>Hide all <i class="bcc-font_up"></i></p>'
: '<p>Show all <i class="bcc-font_down"></i></p>';
}
}
function toggleAllItems() {
const accordionItems = document.querySelectorAll(
'.accordion-button[data-random-id="show-all-with-summary"]'
);
const allExpanded = Array.from(accordionItems).every(
(item) => item.getAttribute("aria-expanded") === "true"
);
for (var i = 0; i < accordionItems.length; i++) {
const item = accordionItems[i];
const target = item.closest(".accordion-header").nextElementSibling;
const icon = item.querySelector("i");
if (allExpanded) {
icon.className = "bcc-font_down";
} else {
icon.className = "bcc-font_up";
}
item.setAttribute("aria-expanded", !allExpanded);
const contentTarget = target.nextElementSibling;
contentTarget.hidden = allExpanded;
}
const topButton = document.querySelector(
"#toggle-all__button-show-all-with-summary"
);
updateToggleAllButton(topButton);
}
window.onload = function () {
const elements = document.querySelectorAll(
'.accordion h2.accordion-heading[data-random-id="show-all-with-summary"]'
);
for (var i = 0; i < elements.length; i++) {
const element = elements[i];
const btn = element.querySelector("button");
const target = element.closest(".accordion-header").nextElementSibling;
const contentID = `accordion-content-${i}`;
target.id = contentID;
btn.setAttribute("aria-controls", contentID);
btn.onclick = function (e) {
e.preventDefault;
let expanded = btn.getAttribute("aria-expanded") === "true";
btn.setAttribute("aria-expanded", !expanded);
const contentTarget = target.nextElementSibling;
contentTarget.hidden = expanded;
const icon = btn.querySelector("i");
if (!expanded) {
contentTarget.focus();
icon.className = "bcc-font_up";
} else {
icon.className = "bcc-font_down";
}
const topButton = document.querySelector(
"#toggle-all__button-show-all-with-summary"
);
updateToggleAllButton(topButton);
};
}
};
With additional show/hide all control
If the accordion is long, you can add another button directly below it so that users don’t have to scroll up the page and lose their place.
- HTML5
- JavaScript
<section class="accordion-block">
<button id="toggle-all__button-show-all-bottom" class="accordion_all-button" onclick="toggleAllItems()">
<p>Show all <i class="bcc-font_down"></i></p>
</button>
<div class="accordion">
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-mmrikb">
Social inclusion
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-mmrikb">The person cannot recognise facial expressions or detail within objects at approximately 6 metres. This significantly impacts upon social inclusion.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-tvfzep">
Physical safety
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-tvfzep">Is physically safe in the educational setting accessing all of the physical environment independently.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-8x128r">
Wellbeing and identity
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-8x128r">Reports to feeling happy in the educational setting. Their emotional wellbeing is good.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-s5516s">
Understanding needs
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-s5516s">Has no visual difficulties or impairment.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-bs24f">
Curriculum access
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-bs24f">Is able to access a full curriculum or chosen college course despite visual impairment.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-3hjxeo">
Eye health
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-3hjxeo">Wears glasses which correct vision sufficiently that vision is not a barrier to learning.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-s4qkym">
Conversational rules
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-s4qkym">The individual understands and follows basic conversational norms, allowing for effective interaction with peers.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-8myf0a">
Functional communication
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-8myf0a">Can express needs and preferences clearly in a variety of settings, aiding in effective communication.</div>
</div>
<div class="accordion-item">
<div class="accordion-header">
<h2 class="accordion-heading" data-random-id="show-all-bottom">
<button type="button" class="accordion-button" aria-expanded="false" data-random-id="show-all-bottom" aria-controls="accordion-content-55rj4g">
Communication - Preparing for adulthood
<i focusable="false" class="bcc-font_down"></i>
</button>
</h2>
</div>
<div hidden="" tabindex="-1" id="accordion-content-55rj4g">Develops skills necessary for independent communication in adult life, including self-advocacy and social skills.</div>
</div>
</div>
<button id="toggle-all__button-bottom-show-all-bottom" class="accordion_all-button accordion_all-button_bottom" onclick="toggleAllItems()"">
<p>Show all <i class="bcc-font_down"></i></p>
</button>
</section>
function updateToggleAllButton(button) {
const accordionItems = document.querySelectorAll(
'.accordion-button[data-random-id="show-all-bottom"]'
);
let allExpanded = true;
for (var i = 0; i < accordionItems.length; i++) {
const item = accordionItems[i];
const isExpanded = item.getAttribute("aria-expanded") === "true";
if (!isExpanded) {
allExpanded = false;
}
}
if (button) {
button.innerHTML = allExpanded
? '<p>Hide all <i class="bcc-font_up"></i></p>'
: '<p>Show all <i class="bcc-font_down"></i></p>';
}
}
function toggleAllItems() {
const accordionItems = document.querySelectorAll(
'.accordion-button[data-random-id="show-all-bottom"]'
);
const allExpanded = Array.from(accordionItems).every(
(item) => item.getAttribute("aria-expanded") === "true"
);
for (var i = 0; i < accordionItems.length; i++) {
const item = accordionItems[i];
const target = item.closest(".accordion-header").nextElementSibling;
const icon = item.querySelector("i");
if (allExpanded) {
icon.className = "bcc-font_down";
} else {
icon.className = "bcc-font_up";
}
item.setAttribute("aria-expanded", !allExpanded);
target.hidden = allExpanded;
}
const topButton = document.querySelector(
"#toggle-all__button-show-all-bottom"
);
updateToggleAllButton(topButton);
const bottomButton = document.querySelector(
"#toggle-all__button-bottom-show-all-bottom"
);
updateToggleAllButton(bottomButton);
}
window.onload = function () {
const elements = document.querySelectorAll(
'.accordion h2.accordion-heading[data-random-id="show-all-bottom"]'
);
for (var i = 0; i < elements.length; i++) {
const element = elements[i];
const btn = element.querySelector("button");
const target = element.closest(".accordion-header").nextElementSibling;
const contentID = `accordion-content-${i}`;
target.id = contentID;
btn.setAttribute("aria-controls", contentID);
btn.onclick = function (e) {
e.preventDefault;
let expanded = btn.getAttribute("aria-expanded") === "true";
btn.setAttribute("aria-expanded", !expanded);
target.hidden = expanded;
const icon = btn.querySelector("i");
if (!expanded) {
target.focus();
icon.className = "bcc-font_up";
} else {
icon.className = "bcc-font_down";
}
const topButton = document.querySelector(
"#toggle-all__button-show-all-bottom"
);
updateToggleAllButton(topButton);
const bottomButton = document.querySelector(
"#toggle-all__button-bottom-show-all-bottom"
);
updateToggleAllButton(bottomButton);
};
}
};