Skip to main content

Your privacy settings

We use cookies to help you with journey planning and relevant disruptions, remember your login and show you content you might be interested in. If you’re happy with the use of cookies by West Midlands Combined Authority and our selected partners, click ‘Accept all cookies’. Or click ‘Manage cookies’ to learn more.

Manage Cookies
Beta

This is a new service - your feedback will help us to improve it.

Components

Accordion

About

What does it do?

  • Allows users to reveal or hide related content on a page

When to use it?

  • When users need only a few key pieces of content on a single page
  • When you want users to have control over the content by expanding it or hiding it (progressive disclosure).
  • When you have long, content rich pages and you need to simplify and reduce the amount of content or keep the content on the single page separated by headings.
  • When you want users to use headings to navigate quickly to specific sections of the page (Information architecture).

When not to use it?

  • When you are presenting essential information and users care about many topics on the page. If users need to open majority of subtopics to have their questions answered, it will require extra effort and click. Hiding content behind navigation diminishes user's awareness of it.

Closed

In its closed state, the accordions .wmnds-accordion__content is hidden from view.

Everything you can see whilst the accordion is in this state is nested within the button.wmnds-accordion-summary-wrapper element.

Take note that:

  • The attribute aria-controls is equal to the id set on the .wmnds-accordion__content element. This helps with accessibility, so that screen readers understand that x button controls x content.
  • The attribute aria-expanded is set to "false" when in the closed state. Again, this helps with accessibility.
  • The only thing not visible in the button.wmnds-accordion-summary-wrapper is the minimise icon.

Lorem ipsum dolar sit...

HTML markup
<div class="wmnds-accordion">
  <button aria-controls="accordion-01" class="wmnds-accordion__summary-wrapper" aria-expanded="false">
    <!-- accordion summary -->
    <div class="wmnds-accordion__summary">
      <h4 class="wmnds-m-b-none">Accordion heading</h4>
    </div>
    <!-- plus icon -->
    <svg class="wmnds-accordion__icon">
      <use xlink:href="#wmnds-general-expand" href="#wmnds-general-expand"></use>
    </svg>
    <!-- minus icon -->
    <svg class="wmnds-accordion__icon wmnds-accordion__icon--minimise">
      <use xlink:href="#wmnds-general-minimise" href="#wmnds-general-minimise"></use>
    </svg>
  </button>
  <!-- accordion content -->
  <div class="wmnds-accordion__content" id="accordion-01">
    Lorem ipsum dolar sit...
  </div>
</div>

Nunjucks markup
{% from "wmnds/components/accordion/_accordion.njk" import wmndsAccordion %}

{{
   wmndsAccordion({
      id: "accordion-01",
      headingText: "Accordion",
      headingHTML: null,
      contentText: null,
      contentHTML: "<p><strong>Some random subtitle</strong></p>
      <p>Lorem ipsum dolor sit...</p>",
      isOpen: false
    })
}}

Nunjucks properties
NameTypeDescription
idstringRequired. Must be unique. Used as an id in the HTML for the accordion as a whole, and also as a prefix for the ids of the section contents and the buttons that open them, so that those ids can be the target of aria-labelledby and aria-control attributes.
headingTextstringRequired. Text content for heading line. If headingHTML is supplied, this is ignored.
headingHTMLstringRequired. HTML content for heading line.
contentTextstringRequired. The text content of each section, which is hidden when the section is closed. If contentHTML is supplied, this is ignored.
contentHTMLstringRequired. The HTML content of each section, which is hidden when the section is closed.
isOpenbooleanIf true, accordion element will be expanded upon initial load. Defaults to false.

Recommended javascript (browser compatible)
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var accordionsJS = function accordionsJS() {
  var accordions = document.querySelectorAll('.wmnds-accordion');
  accordions.forEach(function(accordion) {
    var accordionBtn = accordion.querySelector('.wmnds-accordion__summary-wrapper');

    var toggleAccordion = function toggleAccordion() {
      if (accordion.classList.contains('wmnds-is--open')) {
        accordion.classList.remove('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', false);
      } else {
        accordion.classList.add('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', true);
      }
    };

    accordionBtn.addEventListener('click', toggleAccordion);
  });
};

var _default = accordionsJS;
exports["default"] = _default;

Recommended javascript (ES6)
const accordionsJS = () => {
  const accordions = document.querySelectorAll('.wmnds-accordion');

  accordions.forEach(accordion => {
    const accordionBtn = accordion.querySelector('.wmnds-accordion__summary-wrapper');

    const toggleAccordion = () => {
      if (accordion.classList.contains('wmnds-is--open')) {
        accordion.classList.remove('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', false);
      } else {
        accordion.classList.add('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', true);
      }
    };

    accordionBtn.addEventListener('click', toggleAccordion);
  });
};

export default accordionsJS;

Open

In the open state, the accordion shows all of the content it was initially hiding in the .wmnds-accordion__content element.

To change the accordion to this state, you need to add the modifier class wmnds-is--open to the main .wmnds-accordion element as shown in the code snippet.

Take note that:

  • The attribute aria-expanded is set to "true" when in the open state. Again, this helps with accessibility.
  • The minus icon becomes visible in this state, whilst the plus icon is hidden.

Lorem ipsum dolar sit...

HTML markup
<div class="wmnds-accordion wmnds-is--open">
  <button aria-controls="accordion-open-01" class="wmnds-accordion__summary-wrapper" aria-expanded="true">
    <!-- accordion summary -->
    <div class="wmnds-accordion__summary">
      <h4 class="wmnds-m-b-none">Accordion heading</h4>
    </div>
    <!-- plus icon -->
    <svg class="wmnds-accordion__icon">
      <use xlink:href="#wmnds-general-expand" href="#wmnds-general-expand"></use>
    </svg>
    <!-- minus icon -->
    <svg class="wmnds-accordion__icon wmnds-accordion__icon--minimise">
      <use xlink:href="#wmnds-general-minimise" href="#wmnds-general-minimise"></use>
    </svg>
  </button>
  <!-- accordion content -->
  <div class="wmnds-accordion__content" id="accordion-open-01">
    Lorem ipsum dolar sit...
  </div>
</div>

Nunjucks markup
{% from "wmnds/components/accordion/_accordion.njk" import wmndsAccordion %}

{{
   wmndsAccordion({
      id: "accordion-01",
      headingText: "Accordion",
      headingHTML: null,
      contentText: null,
      contentHTML: "<p><strong>Some random subtitle</strong></p>
      <p>Lorem ipsum dolor sit...</p>",
      isOpen: false
    })
}}

Nunjucks properties
NameTypeDescription
idstringRequired. Must be unique. Used as an id in the HTML for the accordion as a whole, and also as a prefix for the ids of the section contents and the buttons that open them, so that those ids can be the target of aria-labelledby and aria-control attributes.
headingTextstringRequired. Text content for heading line. If headingHTML is supplied, this is ignored.
headingHTMLstringRequired. HTML content for heading line.
contentTextstringRequired. The text content of each section, which is hidden when the section is closed. If contentHTML is supplied, this is ignored.
contentHTMLstringRequired. The HTML content of each section, which is hidden when the section is closed.
isOpenbooleanIf true, accordion element will be expanded upon initial load. Defaults to false.

Recommended javascript (browser compatible)
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var accordionsJS = function accordionsJS() {
  var accordions = document.querySelectorAll('.wmnds-accordion');
  accordions.forEach(function(accordion) {
    var accordionBtn = accordion.querySelector('.wmnds-accordion__summary-wrapper');

    var toggleAccordion = function toggleAccordion() {
      if (accordion.classList.contains('wmnds-is--open')) {
        accordion.classList.remove('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', false);
      } else {
        accordion.classList.add('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', true);
      }
    };

    accordionBtn.addEventListener('click', toggleAccordion);
  });
};

var _default = accordionsJS;
exports["default"] = _default;

Recommended javascript (ES6)
const accordionsJS = () => {
  const accordions = document.querySelectorAll('.wmnds-accordion');

  accordions.forEach(accordion => {
    const accordionBtn = accordion.querySelector('.wmnds-accordion__summary-wrapper');

    const toggleAccordion = () => {
      if (accordion.classList.contains('wmnds-is--open')) {
        accordion.classList.remove('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', false);
      } else {
        accordion.classList.add('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', true);
      }
    };

    accordionBtn.addEventListener('click', toggleAccordion);
  });
};

export default accordionsJS;

Custom

In the example below, you can see that we have customised the summary section of the accordion so that it contains an disruption indicator and some text.

The accordion has been built so that it can easily be customised. You can customise both the summary and the content elements.

To customise the summary (title) section of the accordion, ensure that you nest valid and accessible html within the .wmnds-accordion__summary element.

To customise the content section of the accordion, ensure that you nest valid and accessible html within the .wmnds-accordion__content element.


Some random subtitle

Lorem ipsum dolor sit...


HTML markup
<div class="wmnds-accordion wmnds-is--open">
  <button aria-controls="accordion-custom-01" class="wmnds-accordion__summary-wrapper" aria-expanded="true">
    <!-- accordion summary -->
    <div class="wmnds-accordion__summary">
      <!-- custom summary using grid -->
      <div class="wmnds-grid wmnds-grid--align-center">
        <!-- map pin for bus -->
        <span class="wmnds-disruption-indicator-small wmnds-col-auto wmnds-m-r-md">
          <svg class="wmnds-disruption-indicator-small__icon">
            <use xlink:href="#wmnds-modes-isolated-bus" href="#wmnds-modes-isolated-bus"></use>
          </svg>
          <svg class="wmnds-disruption-indicator-small__icon">
            <use xlink:href="#wmnds-general-warning-circle" href="#wmnds-general-warning-circle"></use>
          </svg>
        </span>
        <div class="wmnds-col-auto">Resurfacing Works at
          <strong>Abbey Street, Lower Gornal</strong>
        </div>
      </div>
    </div>
    <!-- plus icon -->
    <svg class="wmnds-accordion__icon">
      <use xlink:href="#wmnds-general-expand" href="#wmnds-general-expand"></use>
    </svg>
    <!-- minus icon -->
    <svg class="wmnds-accordion__icon wmnds-accordion__icon--minimise">
      <use xlink:href="#wmnds-general-minimise" href="#wmnds-general-minimise"></use>
    </svg>
  </button>
  <!-- accordion content -->
  <div class="wmnds-accordion__content" id="accordion-custom-01">
    <p>
      <strong>Some random subtitle</strong>
    </p>
    <p>
      Lorem ipsum dolor sit...
    </p>
  </div>
</div>

Nunjucks markup
{% from "wmnds/components/accordion/_accordion.njk" import wmndsAccordion %}

{{
   wmndsAccordion({
      id: "accordion-01",
      headingText: "Accordion",
      headingHTML: null,
      contentText: null,
      contentHTML: "<p><strong>Some random subtitle</strong></p>
      <p>Lorem ipsum dolor sit...</p>",
      isOpen: false
    })
}}

Nunjucks properties
NameTypeDescription
idstringRequired. Must be unique. Used as an id in the HTML for the accordion as a whole, and also as a prefix for the ids of the section contents and the buttons that open them, so that those ids can be the target of aria-labelledby and aria-control attributes.
headingTextstringRequired. Text content for heading line. If headingHTML is supplied, this is ignored.
headingHTMLstringRequired. HTML content for heading line.
contentTextstringRequired. The text content of each section, which is hidden when the section is closed. If contentHTML is supplied, this is ignored.
contentHTMLstringRequired. The HTML content of each section, which is hidden when the section is closed.
isOpenbooleanIf true, accordion element will be expanded upon initial load. Defaults to false.

Recommended javascript (browser compatible)
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var accordionsJS = function accordionsJS() {
  var accordions = document.querySelectorAll('.wmnds-accordion');
  accordions.forEach(function(accordion) {
    var accordionBtn = accordion.querySelector('.wmnds-accordion__summary-wrapper');

    var toggleAccordion = function toggleAccordion() {
      if (accordion.classList.contains('wmnds-is--open')) {
        accordion.classList.remove('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', false);
      } else {
        accordion.classList.add('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', true);
      }
    };

    accordionBtn.addEventListener('click', toggleAccordion);
  });
};

var _default = accordionsJS;
exports["default"] = _default;

Recommended javascript (ES6)
const accordionsJS = () => {
  const accordions = document.querySelectorAll('.wmnds-accordion');

  accordions.forEach(accordion => {
    const accordionBtn = accordion.querySelector('.wmnds-accordion__summary-wrapper');

    const toggleAccordion = () => {
      if (accordion.classList.contains('wmnds-is--open')) {
        accordion.classList.remove('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', false);
      } else {
        accordion.classList.add('wmnds-is--open');
        accordionBtn.setAttribute('aria-expanded', true);
      }
    };

    accordionBtn.addEventListener('click', toggleAccordion);
  });
};

export default accordionsJS;