Components: Accordions

A wee design system's library


Accordions #

Accordions are collapsible components. They allow a progressive display of content while reducing irrelevant scrolling down.

Guidelines

Code snippets

The original code for this accordion belongs to Inclusive Design Principles.

Use dark text (#f8f8f8) over a light-coloured area or contrasting image. Make sure that you always provide an accessible colour combination.

Here is an example of proper usage:

Accordion heading

Content heading 1

Content heading 2

These are its code snippets:

                            
                                
HTML
<h3 class="heading heading-button" tabindex="-1"> <span>Accordion heading</span> <button class="btn" data-expandall="">Expand all</button> </h3> <div class="component-container"> <div class="component-intro"> <h4 id="accdn-xmpl1">Content heading 1</h4> <button data-expands="accdn-xmpl1-content" aria-label="open section" aria-describedby="accdn-xmpl1" aria-expanded="false"> <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70"> <g transform="translate(0 -981.5)"> <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect> <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect> </g> </svg> </button> </div> <div id="accdn-xmpl1-content" class="component-content" hidden=""> <p>This is the content 1.</p> </div> </div> <div class="component-container"> <div class="component-intro"> <h4 id="accdn-xmpl2">Content heading 2</h4> <button data-expands="accdn-xmpl2-content" aria-label="open section" aria-describedby="accdn-xmpl2" aria-expanded="false"> <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70"> <g transform="translate(0 -981.5)"> <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect> <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect> </g> </svg> </button> </div> <div id="accdn-xmpl2-content" class="component-content" hidden=""> <p>This is the content 2.</p> </div> </div>
CSS
[hidden] { display: none; margin-top: 0; } /* button::-moz-focus-inner { border: 0; } */ /* fix for IE */ div[tabindex]:focus { outline: none; } .component-container { border-bottom: 2px dotted #cccccc; margin-bottom: 1rem; padding: .125rem 0 1rem; } .component-intro, .heading-button { align-items: center; display: flex; justify-content: space-between; line-height: 1; } .component-intro button { background: 0; border: 0; border-bottom: 2px solid #f8f8f8; color: #dd2808; margin: 0; } .code-example { background-color: #f0f0f0; border-radius: 3px; justify-content: left; margin: 1rem 0; padding: 1rem; } .component h4 { cursor: pointer; margin: 1rem 0; } .component-intro ~ .component-intro { border-top: 1px dashed; padding-top: 1rem; } button i::before { color: #dd2808; } [data-expands] svg { height: 1.25rem; width: 1.25rem; } [data-expands][aria-expanded="true"] .up-strut { display: none; } [data-expands]:hover svg g { color: #dd2808; } @media print { [hidden] { display: block !important; } [data-expandall], [data-expands], .examples + p { display: none !important; } } p { font: normal 1rem/1.6 'Georgia', Times, serif; margin: 1.125rem 0; } h4 { font: 700 1.266rem/1.2 'Raleway', Helvetica, sans-serif; }
JS
(function() { var translations = { en: { EXPAND: "Expand all", COLLAPSE: "Collapse all" }, es: { EXPAND: "muestra todo", COLLAPSE: "esconde todos" }, fr: { EXPAND: "ouvrir tout", COLLAPSE: "fermer tout" }, }; var pageLang = document.querySelector('html').getAttribute('lang'); var strings = translations[pageLang] || translations['en']; function collapse(toggle, target) { toggle.setAttribute('aria-expanded', 'false'); target.hidden = true; } function expand(toggle, target) { toggle.setAttribute('aria-expanded', 'true'); target.hidden = false; } var toggles = document.querySelectorAll('[data-expands]'); [].forEach.call(toggles, function(toggle) { toggle.hidden = false; toggle.setAttribute('aria-expanded', 'false'); var target = document.getElementById(toggle.getAttribute('data-expands')); if (target) { target.hidden = true; toggle.addEventListener('click', function() { var expanded = (this.getAttribute('aria-expanded') === 'true'); if (expanded) { collapse(this, target); } else { expand(this, target); } }); } }); if(!document.querySelector('[data-expandAll]')){ return; } var expandAll = document.querySelector('[data-expandAll]'); expandAll.hidden = false; expandAll.textContent = strings.EXPAND; expandAll.addEventListener('click', function() { var expanded = this.textContent === strings.EXPAND ? false : true; if (expanded) { [].forEach.call(toggles, function(toggle) { var target = document.getElementById(toggle.getAttribute('data-expands')); collapse(toggle, target); }); this.textContent = strings.EXPAND; } else { [].forEach.call(toggles, function(toggle) { var target = document.getElementById(toggle.getAttribute('data-expands')); expand(toggle, target); }); this.textContent = strings.COLLAPSE; } }); function openSection() { var hash = window.location.hash || false; if (hash) { var id = hash.substring(1); var sectionToggle = document.querySelector('[data-expands='+id+'-content]') || false; if (sectionToggle) { if (sectionToggle.getAttribute('aria-expanded') === 'false') { sectionToggle.click(); } } } } window.onload = openSection; window.onhashchange = openSection; var sectionHeadings = document.querySelectorAll('.component-intro h4'); Array.prototype.forEach.call(sectionHeadings, function (heading) { heading.addEventListener('click', function () { this.nextElementSibling.click(); }) }); })();

Sources of inspiration

See buttons as a component