Cookies on ons.gov.uk

Cookies are small files stored on your device when you visit a website. We use some essential cookies to make this website work.

We would like to set additional cookies to remember your settings and understand how you use the site. This helps us to improve our services.

You have accepted all additional cookies. You have rejected all additional cookies. You can change your cookie preferences at any time.

Skip to main content

Accordion

Overview

Accordions let users show or hide sections of related content on the same page.

Example Accordion contents

Nunjucks

{% from "components/accordion/_macro.njk" import onsAccordion %}

{{
    onsAccordion({
        "id": "accordion-example",
        "allButton": {
            "open": "Show all",
            "close": "Hide all"
        },
        "itemsList": [
            {
                "title": "Total retail turnover",
                "content": "<h3 class=\"ons-u-fs-r\">Include:</h3><ul class=\"ons-list\"><li class=\"ons-list__item\">VAT</li><li class=\"ons-list__item\">internet sales</li><li class=\"ons-list__item\">retail sales from outlets in Great Britain to <a href=\"#\">customers abroad</a></li></ul><h3 class=\"ons-u-fs-r\">Exclude:</h3><ul class=\"ons-list\"><li class=\"ons-list__item\">revenue from mobile phone network commission and top-up</li><li class=\"ons-list__item\">sales from catering facilities used by customers</li><li class=\"ons-list__item\">lottery sales and commission from lottery sales</li><li class=\"ons-list__item\">sales of car accessories and motor vehicles</li><li class=\"ons-list__item\">NHS receipts</li><li class=\"ons-list__item\">automotive fuel</li></ul>"
            },
            {
                "title": "Food sales",
                "content": "<h3 class=\"ons-u-fs-r\">Include:</h3><ul class=\"ons-list\"><li class=\"ons-list__item\">all fresh food</li><li class=\"ons-list__item\">other food for human consumption (except chocolate and sugar confectionery)</li><li class=\"ons-list__item\">soft drinks</li></ul><h3 class=\"ons-u-fs-r\">Exclude:</h3><ul class=\"ons-list\"><li class=\"ons-list__item\">sales from catering facilities used by customers</li></ul>"
            },
            {
                "title": "Alcohol, confectionery, soft drinks and tobacco sales",
                "content": "<h3 class=\"ons-u-fs-r\">Include:</h3><ul class=\"ons-list\"><li class=\"ons-list__item\">chocolate and sugar confectionery</li><li class=\"ons-list__item\">tobacco and smokers’ requisites</li></ul>"
            }
        ]
    })
}}

Nunjucks macro options

NameTypeRequiredDescription
idstringtrueid of the accordion
classesstringfalseClasses to add to the accordion component
itemsListArray<AccordionItem>trueAn array of accordion items
allButtonObject<AccordionButton>falseSettings for the accordion button to show or hide the contents of all the accordion items. If not set, the button will not render.
saveStatebooleanfalseSaves the state of any open accordion items to local storage so they remain open when the page reloads
openbooleanfalseForces all accordion items to be open when the page loads
AccordionItem
NameTypeRequiredDescription
titlestringtrueThe title of the accordion item
headingLevelintfalseNumber used to determine the heading level of the title. Use to ensure the title has a correct semantic order on the page. Defaults to 2
contentstringtrueThe content of the accordion item
attributesobjectfalseHTML attributes (for example, data attributes) to add to the details element
headingAttributesobjectfalseHTML attributes (for example, data attributes) to add to the details header element
contentAttributesobjectfalseHTML attributes (for example, data attributes) to add to the details content element
AccordionButton
NameTypeRequiredDescription
openstringtrueButton label text to show when one or more accordion items are closed
closestringtrueButton label text to show when all of the items are open
attributesobjectfalseHTML attributes (for example, data attributes) to add to the button

HTML

<div id="accordion-example" class="ons-accordion">
  <button type="button"
    class="ons-btn ons-accordion__toggle-all ons-u-mb-s ons-u-d-no ons-btn--secondary ons-btn--small"
    data-close-all="Hide all" data-group="accordion-example">
    <span class="ons-btn__inner ons-accordion__toggle-all-inner"><span class="ons-btn__text">Show all</span></span>
  </button>
  <div id="accordion-example-1" class="ons-details ons-js-details ons-details--accordion"
    data-group="accordion-example">
    <div class="ons-details__heading ons-js-details-heading" role="button">
      <h2 class="ons-details__title ons-u-fs-r--b">Total retail turnover</h2>
      <span class="ons-details__icon">
        <svg class="ons-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false"
          fill="currentColor" role="img" title="ons-icon-chevron">
          <path
            d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z"
            transform="translate(-5.02 -1.59)" />
        </svg></span>
    </div>
    <div id="accordion-example-1-content" class="ons-details__content ons-js-details-content">
      <h3 class="ons-u-fs-r">Include:</h3>
      <ul class="ons-list">
        <li class="ons-list__item">VAT</li>
        <li class="ons-list__item">internet sales</li>
        <li class="ons-list__item">retail sales from outlets in Great Britain to <a href="#">customers abroad</a></li>
      </ul>
      <h3 class="ons-u-fs-r">Exclude:</h3>
      <ul class="ons-list">
        <li class="ons-list__item">revenue from mobile phone network commission and top-up</li>
        <li class="ons-list__item">sales from catering facilities used by customers</li>
        <li class="ons-list__item">lottery sales and commission from lottery sales</li>
        <li class="ons-list__item">sales of car accessories and motor vehicles</li>
        <li class="ons-list__item">NHS receipts</li>
        <li class="ons-list__item">automotive fuel</li>
      </ul>
    </div>
  </div>
  <div id="accordion-example-2" class="ons-details ons-js-details ons-details--accordion"
    data-group="accordion-example">
    <div class="ons-details__heading ons-js-details-heading" role="button">
      <h2 class="ons-details__title ons-u-fs-r--b">Food sales</h2>
      <span class="ons-details__icon">
        <svg class="ons-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false"
          fill="currentColor" role="img" title="ons-icon-chevron">
          <path
            d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z"
            transform="translate(-5.02 -1.59)" />
        </svg></span>
    </div>
    <div id="accordion-example-2-content" class="ons-details__content ons-js-details-content">
      <h3 class="ons-u-fs-r">Include:</h3>
      <ul class="ons-list">
        <li class="ons-list__item">all fresh food</li>
        <li class="ons-list__item">other food for human consumption (except chocolate and sugar confectionery)</li>
        <li class="ons-list__item">soft drinks</li>
      </ul>
      <h3 class="ons-u-fs-r">Exclude:</h3>
      <ul class="ons-list">
        <li class="ons-list__item">sales from catering facilities used by customers</li>
      </ul>
    </div>
  </div>
  <div id="accordion-example-3" class="ons-details ons-js-details ons-details--accordion"
    data-group="accordion-example">
    <div class="ons-details__heading ons-js-details-heading" role="button">
      <h2 class="ons-details__title ons-u-fs-r--b">Alcohol, confectionery, soft drinks and tobacco sales</h2>
      <span class="ons-details__icon">
        <svg class="ons-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false"
          fill="currentColor" role="img" title="ons-icon-chevron">
          <path
            d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z"
            transform="translate(-5.02 -1.59)" />
        </svg></span>
    </div>
    <div id="accordion-example-3-content" class="ons-details__content ons-js-details-content">
      <h3 class="ons-u-fs-r">Include:</h3>
      <ul class="ons-list">
        <li class="ons-list__item">chocolate and sugar confectionery</li>
        <li class="ons-list__item">tobacco and smokers’ requisites</li>
      </ul>
    </div>
  </div>
</div>

When to use this component

Use this component when you have identified a strong user need to quickly scan large sections of content, by condensing them into an overview of section headings, and show and hide those sections as needed.

Accordions can benefit repeat users who need to regularly perform the same familiar tasks quickly, where they only need a few key pieces of the content to proceed.

When not to use this component

Accordions hide content from users and are not easily noticed and understood by everyone. So they should not be used if the content inside each accordion is critical to the user being able to progress with their task.

Test your content considering the following alternatives before using accordions:

  • simplify the content to reduce down the amount
  • separate the content with headings
  • use page contents links to enable users to quickly to navigate to sections of content
  • divide the content across multiple pages

Alternative components

Accordions, tabs and details all hide sections of content which a user can show or hide.

Tabs may work better for users who need to switch quickly between sections because the position of their headings remains static, whereas the accordion headings move down the page as you open others.

Consider the number of sections you need to display. Tabs display horizontally so cannot display as many sections as accordions which display vertically. Also consider the use of your service on mobile devices. Tabs only display above 640px before their content is expanded and stacked vertically under headings.

Use the details component if there is only one section of content that needs to be condensed.

How to use this component

The functionality of accordions is provided by grouping details components together.

Use clear labels

Accordions hide content so make sure your section headings are clear so the user does not need to work hard to understand which heading to choose.

Variants

Open

Under certain conditions setting each item to be open by default may be appropriate. The example below shows the accordion being used in a narrow column for filtering results.

The allButton property has not been configured and won't be rendered to allow the accordion to fit into a smaller area.

To use this variant include the parameter 'open': true in your implementation.

Example Accordion Open contents

Nunjucks
{% from "components/accordion/_macro.njk" import onsAccordion %}
{% from "components/checkboxes/_macro.njk" import onsCheckboxes %}

{% set content1 %}
    {{
        onsCheckboxes({
            "checkboxesLabel": "Show only:",
            "legend": "Content type",
            "legendClasses": "ons-u-vh",
            "classes": "ons-u-mb-s",
            "borderless": true,
            "name": "dietary",
            "checkboxes": [
                {
                    "id": "data-checkbox",
                    "label": {
                        "text": "Data (309)"
                    },
                    "value": "data"
                },
                {
                    "id": "publications-checkbox",
                    "label": {
                        "text": "Publications (137)"
                    },
                    "value": "publications",
                    "other": {
                        "otherType": "checkboxes",
                        "selectAllChildren": true,
                        "legend": "Publication type",
                        "legendClasses": "ons-u-vh",
                        "name": "name",
                        "checkboxes": [
                            {
                                "id": "datasets-checkbox",
                                "label": {
                                    "text": "Datasets (100)"
                                },
                                "value": "datasets"
                            },
                            {
                                "id": "timeseries-checkbox",
                                "label": {
                                    "text": "Timeseries (20)"
                                },
                                "value": "timeseries"
                            },
                            {
                                "id": "requested-checkbox",
                                "label": {
                                    "text": "User requested data (16)"
                                },
                                "value": "requested"
                            }
                        ]
                    }
                },
                {
                    "id": "areas-checkbox",
                    "label": {
                        "text": "Areas (0)"
                    },
                    "value": "areas"
                }
            ]
        })
    }}
{% endset %}
{% set content2 %}
    {{
        onsCheckboxes({
            "checkboxesLabel": "Show only:",
            "legend": "Topic",
            "legendClasses": "ons-u-vh",
            "classes": "ons-u-mb-s",
            "borderless": true,
            "name": "dietary",
            "checkboxes": [
                {
                    "id": "crime-checkbox",
                    "label": {
                        "text": "Crime (200)"
                    },
                    "value": "crime",
                    "checked": true
                },
                {
                    "id": "education-checkbox",
                    "label": {
                        "text": "Education (55)"
                    },
                    "value": "education-checkbox"
                },
                {
                    "id": "disability-checkbox",
                    "label": {
                        "text": "Disability (67)"
                    },
                    "value": "disability"
                }
            ]
        })
    }}
{% endset %}

<div class="ons-grid">
    <div class="ons-grid__col ons-col-4@m">
        {{
            onsAccordion({
                "id": "accordion",
                "open": true,
                "itemsList": [
                    {
                        "title": "Content type",
                        "content": content1
                    },
                    {
                        "title": "Topic",
                        "content": content2
                    }
                ]
            })
        }}
    </div>
</div>
Nunjucks macro options
NameTypeRequiredDescription
idstringtrueid of the accordion
classesstringfalseClasses to add to the accordion component
itemsListArray<AccordionItem>trueAn array of accordion items
allButtonObject<AccordionButton>falseSettings for the accordion button to show or hide the contents of all the accordion items. If not set, the button will not render.
saveStatebooleanfalseSaves the state of any open accordion items to local storage so they remain open when the page reloads
openbooleanfalseForces all accordion items to be open when the page loads
AccordionItem
NameTypeRequiredDescription
titlestringtrueThe title of the accordion item
headingLevelintfalseNumber used to determine the heading level of the title. Use to ensure the title has a correct semantic order on the page. Defaults to 2
contentstringtrueThe content of the accordion item
attributesobjectfalseHTML attributes (for example, data attributes) to add to the details element
headingAttributesobjectfalseHTML attributes (for example, data attributes) to add to the details header element
contentAttributesobjectfalseHTML attributes (for example, data attributes) to add to the details content element
AccordionButton
NameTypeRequiredDescription
openstringtrueButton label text to show when one or more accordion items are closed
closestringtrueButton label text to show when all of the items are open
attributesobjectfalseHTML attributes (for example, data attributes) to add to the button
HTML
<div class="ons-grid">
  <div class="ons-grid__col ons-col-4@m">
    <div id="accordion" class="ons-accordion">
      <div id="accordion-1" class="ons-details ons-js-details ons-details--accordion" data-group="accordion"
        data-open="true">
        <div class="ons-details__heading ons-js-details-heading" role="button">
          <h2 class="ons-details__title ons-u-fs-r--b">Content type</h2>
          <span class="ons-details__icon">
            <svg class="ons-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false"
              fill="currentColor" role="img" title="ons-icon-chevron">
              <path
                d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z"
                transform="translate(-5.02 -1.59)" />
            </svg></span>
        </div>
        <div id="accordion-1-content" class="ons-details__content ons-js-details-content">
          <fieldset class="ons-fieldset ons-u-mb-s">
            <legend class="ons-fieldset__legend ons-u-vh"><span class="ons-fieldset__legend-title ons-u-pb-no">Content
                type</span></legend>
            <p class="ons-checkboxes__label"> Show only: </p>
            <div class="ons-checkboxes__items">
              <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                <span class="ons-checkbox  ons-checkbox--no-border">
                  <input type="checkbox" id="data-checkbox" class="ons-checkbox__input ons-js-checkbox" value="data" />
                  <label class=" ons-checkbox__label" for="data-checkbox" id="data-checkbox-label">Data (309)</label>
                </span>
              </span>
              <br />
              <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                <span class="ons-checkbox  ons-checkbox--no-border">
                  <input type="checkbox" id="publications-checkbox"
                    class="ons-checkbox__input ons-js-checkbox  ons-js-other ons-js-select-all-children"
                    value="publications" aria-controls="publications-checkbox-other-wrap" aria-haspopup="true" />
                  <label class=" ons-checkbox__label" for="publications-checkbox"
                    id="publications-checkbox-label">Publications (137)</label>
                  <span class="ons-checkbox__other" id="publications-checkbox-other-wrap">
                    <fieldset class="ons-fieldset ons-js-other-fieldset-checkbox">
                      <legend class="ons-fieldset__legend ons-u-vh"><span
                          class="ons-fieldset__legend-title ons-u-pb-no">Publication type</span></legend>
                      <div class="ons-checkboxes__items">
                        <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                          <span class="ons-checkbox  ons-checkbox--no-border">
                            <input type="checkbox" id="datasets-checkbox" class="ons-checkbox__input ons-js-checkbox"
                              value="datasets" />
                            <label class=" ons-checkbox__label" for="datasets-checkbox"
                              id="datasets-checkbox-label">Datasets (100)</label>
                          </span>
                        </span>
                        <br />
                        <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                          <span class="ons-checkbox  ons-checkbox--no-border">
                            <input type="checkbox" id="timeseries-checkbox" class="ons-checkbox__input ons-js-checkbox"
                              value="timeseries" />
                            <label class=" ons-checkbox__label" for="timeseries-checkbox"
                              id="timeseries-checkbox-label">Timeseries (20)</label>
                          </span>
                        </span>
                        <br />
                        <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                          <span class="ons-checkbox  ons-checkbox--no-border">
                            <input type="checkbox" id="requested-checkbox" class="ons-checkbox__input ons-js-checkbox"
                              value="requested" />
                            <label class=" ons-checkbox__label" for="requested-checkbox"
                              id="requested-checkbox-label">User requested data (16)</label>
                          </span>
                        </span>
                      </div>
                    </fieldset>
                  </span>
                </span>
              </span>
              <br />
              <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                <span class="ons-checkbox  ons-checkbox--no-border">
                  <input type="checkbox" id="areas-checkbox"
                    class="ons-checkbox__input ons-js-checkbox  ons-js-other ons-js-select-all-children"
                    value="areas" />
                  <label class=" ons-checkbox__label" for="areas-checkbox" id="areas-checkbox-label">Areas (0)</label>
                </span>
              </span>
            </div>
          </fieldset>
        </div>
      </div>
      <div id="accordion-2" class="ons-details ons-js-details ons-details--accordion" data-group="accordion"
        data-open="true">
        <div class="ons-details__heading ons-js-details-heading" role="button">
          <h2 class="ons-details__title ons-u-fs-r--b">Topic</h2>
          <span class="ons-details__icon">
            <svg class="ons-icon" viewBox="0 0 8 13" xmlns="http://www.w3.org/2000/svg" focusable="false"
              fill="currentColor" role="img" title="ons-icon-chevron">
              <path
                d="M5.74,14.28l-.57-.56a.5.5,0,0,1,0-.71h0l5-5-5-5a.5.5,0,0,1,0-.71h0l.57-.56a.5.5,0,0,1,.71,0h0l5.93,5.93a.5.5,0,0,1,0,.7L6.45,14.28a.5.5,0,0,1-.71,0Z"
                transform="translate(-5.02 -1.59)" />
            </svg></span>
        </div>
        <div id="accordion-2-content" class="ons-details__content ons-js-details-content">
          <fieldset class="ons-fieldset ons-u-mb-s">
            <legend class="ons-fieldset__legend ons-u-vh"><span
                class="ons-fieldset__legend-title ons-u-pb-no">Topic</span></legend>
            <p class="ons-checkboxes__label"> Show only: </p>
            <div class="ons-checkboxes__items">
              <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                <span class="ons-checkbox  ons-checkbox--no-border">
                  <input type="checkbox" id="crime-checkbox" class="ons-checkbox__input ons-js-checkbox" value="crime"
                    checked />
                  <label class=" ons-checkbox__label" for="crime-checkbox" id="crime-checkbox-label">Crime (200)</label>
                </span>
              </span>
              <br />
              <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                <span class="ons-checkbox  ons-checkbox--no-border">
                  <input type="checkbox" id="education-checkbox" class="ons-checkbox__input ons-js-checkbox"
                    value="education-checkbox" />
                  <label class=" ons-checkbox__label" for="education-checkbox" id="education-checkbox-label">Education
                    (55)</label>
                </span>
              </span>
              <br />
              <span class="ons-checkboxes__item ons-checkboxes__item--no-border">
                <span class="ons-checkbox  ons-checkbox--no-border">
                  <input type="checkbox" id="disability-checkbox" class="ons-checkbox__input ons-js-checkbox"
                    value="disability" />
                  <label class=" ons-checkbox__label" for="disability-checkbox"
                    id="disability-checkbox-label">Disability (67)</label>
                </span>
              </span>
            </div>
          </fieldset>
        </div>
      </div>
    </div>
  </div>
</div>

Help improve this page

Let us know how we could improve this page, or share your user research findings. Discuss the ‘Accordion’ component on GitHub (opens in a new tab)