Robust and accessible

  • As it relies on a basic HTML structure (Hx and contents), even if the JavaScript isn’t loaded, your page will work, it’s the miracle of progressive enhancement;
  • It is based on ARIA Design Pattern for accordions;
  • No inline CSS/JavaScript injected, your DOM stays clean, which is cool for responsive.

It’s (highly) customisable

  • You can style it as you want;
  • You can set up transitions or animations… as you want;
  • You can create namespaces for generated classes if you need different behaviours in the same page;
  • Every aspect of the script can be customized, default config may be overwritten on plugin call, if you transpile the script into ES5, it will be IE9+ compatible.

Free and no license problem

  • No license problem: it uses MIT license, so it’s free, open-source and you can do whatever you want with it, including commercial use. This permission notice shall be included in all copies or substantial portions of it.
  • However, it is not prohibited to tell me that you’ve used it, or send me a little “thank you”. ;)

Lightweight

  • 20kb (development, readable by humans);
  • ~8kb (minified, readable by machines);
  • ~2.8kb minified and gzipped (readable by… mutants‽‽)

How it is working

Basically it will transform this:

<div class="js-accordion" data-accordion-prefix-classes="your-prefix-class">
 <h2 class="js-accordion__header">First tab</h2>
 <div class="js-accordion__panel">
   <p>Content of 1st tab</p>
 </div>
 <h2 class="js-accordion__header">Second tab</h2>
 <div class="js-accordion__panel">
   <p>Content of 2nd tab</p>
 </div>
 <h2 class="js-accordion__header">Third tab</h2>
 <div class="js-accordion__panel">
   <p>Content of 3rd tab</p>
 </div>
</div>

Into this:

<div class="your-prefix-class" 
   data-accordion-prefix-classes="your-prefix-class"
   role="tablist" aria-multiselectable="true">

 <h2 class="your-prefix-class-accordion__title">
 <button id="accordion1_tab1" 
     class="js-accordion__header your-prefix-class-accordion__header" 
     aria-controls="accordion1_panel1" aria-expanded="false" 
     role="tab" aria-selected="true" type="button">
       First tab
 </button>
 </h2>

 <div id="accordion1_panel1" 
     class="js-accordion__panel your-prefix-class-accordion__panel" 
     aria-labelledby="accordion1_tab1" 
     role="tabpanel" aria-hidden="true">

   <p>Content of 1st tab</p>

 </div>
 … etc…
</div>

The plugin will do the rest (all ids, ARIA attributes, buttons are generated on the fly).

The script is launched when the page is loaded. If you need to execute it on AJAX-inserted content, you may use for example on <div id="newContent">your accordion source</div>:

var my_accordion = van11yAccessibleAccordionAria();
my_accordion.attach(document.getElementById('newContent'));

How to use it

You may use npm command: npm i van11y-accessible-accordion-aria.
You may also use bower: bower install van11y-accessible-accordion-aria.

Then, follow the conventions given in this minimal example.

<div class="js-accordion" data-accordion-prefix-classes="your-prefix-class">
 <h2 class="js-accordion__header">First tab</h2>
 <div class="js-accordion__panel">
   <p>Content of 1st tab</p>
 </div>
 <h2 class="js-accordion__header">Second tab</h2>
 <div class="js-accordion__panel">
   <p>Content of 2nd tab</p>
 </div>
 <h2 class="js-accordion__header">Third tab</h2>
 <div class="js-accordion__panel">
   <p>Content of 3rd tab</p>
 </div>
</div>

The minimal style needed is:

.your-prefix-class-accordion__panel[aria-hidden=true] {
  display: none;
}

const CONFIG = {
    ACCORDION_JS: 'js-accordion',
    ACCORDION_JS_HEADER: 'js-accordion__header',
    ACCORDION_JS_PANEL: 'js-accordion__panel',

    ACCORDION_DATA_PREFIX_CLASS: 'data-accordion-prefix-classes',
    ACCORDION_DATA_OPENED: 'data-accordion-opened',
    ACCORDION_DATA_MULTISELECTABLE: 'data-accordion-multiselectable',
    ACCORDION_DATA_COOL_SELECTORS: 'data-accordion-cool-selectors',

    ACCORDION_PREFIX_IDS: 'accordion',
    ACCORDION_BUTTON_ID: '_tab',
    ACCORDION_PANEL_ID: '_panel',

    ACCORDION_STYLE: 'accordion',
    ACCORDION_TITLE_STYLE: 'accordion__title',
    ACCORDION_HEADER_STYLE: 'accordion__header',
    ACCORDION_PANEL_STYLE: 'accordion__panel',

    ACCORDION_ROLE_TABLIST: 'tablist',
    ACCORDION_ROLE_TAB: 'tab',
    ACCORDION_ROLE_TABPANEL: 'tabpanel',

    ATTR_ROLE: 'role',
    ATTR_MULTISELECTABLE: 'aria-multiselectable',
    ATTR_EXPANDED: 'aria-expanded',
    ATTR_LABELLEDBY: 'aria-labelledby',
    ATTR_HIDDEN: 'aria-hidden',
    ATTR_CONTROLS: 'aria-controls',
    ATTR_SELECTED: 'aria-selected',
    ...config
};

If you need to use another configuration, you may call the plugin like this:

var other_accordion = van11yAccessibleAccordionAria({
    ACCORDION_PREFIX_IDS: 'peekaboo_',
    ACCORDION_JS: 'js-accordion2'
});
other_accordion.attach();

And everything will be working as you need.