A tiny module to manage height transition in multiple (or even just one) elements without pain. It uses CSS transition in order to have a fluid and smooth movement. It use aria-hidden and aria-expanded to facilitate accessibility. It puts intermediate classes to see if the accordion is opening and to understand when and how to put display none (also for accessibility)
https://codepen.io/cant89/pen/RLEoyV
- Add to your project
Add gianniAccordion.min.js
to your project including it before your closing body
tag:
<script type="text/javascript" src="/path/to/your/repository/gianniAccordion.min.js"></script>
- Prepare your HTML:
<article class="expandableItem">
<div data-accordion-element-trigger>This is a title</div>
<div data-accordion-element-content>This is a looong content</p>
</article>
<article class="expandableItem">
<div data-accordion-element-trigger>This is a title</div>
<div data-accordion-element-content>This is a looong content</p>
</article>
...
- Initialize it in your script:
var myAccordion = new gianniAccordion({
elements: '.your-accordion-element-class',
trigger: "[data-accordion-element-trigger]",
content: "[data-accordion-element-content]",
// collapsedHeight: '135px' -> maybe you have only one accordion and the content is partial visible
// selectedClass: 'my-custom-selected-class' -> by default is 'selected'
// openAtLandingIndex: 2 -> set 3rd element open at landing
});
- Add a little bit, but necessary, style:
[data-accordion-element-content] {
height: auto;
overflow: hidden;
transition: height .5s;
/** will-change: height; **/
}
- Enjoy with Gianni! :)
-
elements (this is the only one mandatory option)
Css selector of the elements for which you want to enable accordion.
It is expected to have two childrens: an expandable one that here we call "content", and the "trigger" one that manage the visibility of the "content"
-
trigger
Css selector for the Trigger inside the element (it will be searched inside the
elements
selector)default is
[data-accordion-element-trigger]
-
content
Css selector for the Content inside the element (it will be searched inside the
elements
selector)default is
[data-accordion-element-content]
-
oneAtATime
If true, when an element is clicked the others elements will be closed.
default is
true
-
selectedClass
Css Class added to the element when it is selected
default is
selected
-
collapsedHeight
min height for the content in (ex 120px or 2rem or similar)
default is
0
-
openAtLandingIndex
index of the element that will be opened at landing
default is
-1
You can listen for events using the .on() method.
It accepts two arguments:
- The name of the event (string)
- A function to execute, which will retreive an argument with some useful data (fn)
Eg:
myAccordion.on( "elementSelected", function elementIsSelected(data){
// Do something
})
Here all the available events:
-
elementSelected
fired when an element is clicked (but still not opened)
-
elementOpened
fired when an element is selected and the opening transition is ended
-
elementUnselected
fired when an element is unselected (but still not closed)
-
elementClosed
fired when an element is unselected and the closing transition is ended
-
elementSelectedAtLanding
fired when an element is selected at landing (triggered by the openAtLandingIndex option)
NOTE: this library use style.scrollHeight property to determine the height of the scrollable content of the element you pass in, so every css rule (like translateY), applied on childrens of that element, that affect the scrollable area, could be result in a wrong calculation of the height. Applied that to the element instead.