Accordion with HTML, CSS (SASS) and JavaScript.
Share on

Accordion with HTML, CSS (SASS) and JavaScript.

Oh hi there 👋 dont miss out by subscribing.

This Tutorial will make a reusable Accordion Component with HTML, CSS (Sass), and JavaScript. We will make it, so we only have to provide a minimal HTML structure with a few classes for the accordion to work. We’ll handle most of it in JS and CSS.

So let us get right into coding.

HTML of the Accordion

As mentioned above, we make it so we can use the accordion anywhere. We need a div with the class accordion, with two child divs, one with the class accordion-title and one with the class accordion-body. The body is the part that will be collapsed. We can give it the collapsed Class by default, so it is collapsed by default.

<div class="accordion">
    <div class="accordion-title">Accordion Title</div>
    <div class="accordion-body collapsed">
		The body of the accordion will be collapsed.

So that’s it for the HTML of the Accordion. You can use this anywhere in your code if you import the CSS and js correctly.

SASS / CSS of the Accordion

Now let us get to the styling of the accordion. Remember that this won’t work without JavaScript, but it will look nice. We do this with the preprocessor SASS, but we don’t utilize many of the features offered. I can work better with CSS if I do it via SASS, but that’s just me.

So we start by setting the font, margin, background color, and border for our accordion class.

    font-family: 'Segoe UI', sans-serif
    margin-bottom: 1em
    background-color: RGB(240, 240, 240)
    border: 5px solid RGB(85, 214, 145)

Then we style the accordion-title by nesting it within the accordion class. We must set its display to flex and its justify-content to space-between and the align-item to center. Later we will insert an icon into the title, and we want that it is vertically centered on the text and at the end.

        padding: 1em
        font-size: 1.3em
        display: flex
        justify-content: space-between
        align-items: center

Now, if the user hovers over the title, we set different background colors and the cursor to the pointer, which is the hand. The accordion-title-icon will be inserted by js and is an SVG Path, so we can use fill to change its color.

            background-color: RGB(230, 230, 230)
            cursor: pointer

            width: 30px
            fill:  rgb(170, 170, 170)

Last but not least, we apply a bit of styling to the accordion-body, and we say that elements with the class collapsed have the display: none.

        padding: 1em
        border-top: 3px solid RGB(210, 210, 210)

        display: none

That’s it for the CSS.

JavaScript of the Accordion

Now let us get to the JavaScript of the accordion. We start by getting all the elements with the accordion class using the querySelectorAll function. The function will return an HTML collection, but we need an Array to loop over it, so we transform it with Array.from(obj). Then we use the forEach() function to loop over it with a function called for each iteration. We save the current object in the el variable.

/* Loop through all elements with the accordion class */
Array.from(document.querySelectorAll('.accordion')).forEach(el => {

In the loop, we get the accordion title and accordion body divs by using the querySelector method on the object we currently have. Now the querySelector function returns the first item that matches the selector.

    /* Save important Element References */
    let accordionTitle = el.querySelector('.accordion-title');
    let accordionBody = el.querySelector('.accordion-body');

Then we replace the inner HTML of the accordion title with some more complex HTML, but we get the previous inner HTML and reinsert it but we also insert an SVG path that is a simple arrow down.

    /* Reinsert the Title with an Icon */
    accordionTitle.innerHTML = `
    <svg xmlns="" viewBox="0 0 448 512" class="accordion-title-icon">
        <path d="M224 416c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L224 338.8l169.4-169.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-192 192C240.4 412.9 232.2 416 224 416z"/>

Now we also get the accordion title icon that we just inserted.

    let accordionTitleIcon = el.querySelector('.accordion-title-icon');

After that, we define a function that toggles the collapsed Class for the body, and we rotate the icon dependent on the state of the body. We do this with a ternary operator.

    /* Call this function when clicking on the title */
    let toggle = function() {

        /* Use el.classList.toggle(name) to toggle the class in the Element */

        /* Set the Icon Rotation depending on whether the collapsed Class has been set. */ = accordionBody.classList.contains('collapsed') ? 'rotate(0deg)' : 'rotate(180deg)'

Then we connect the click event on the accordion title with the function we just made.

    /* Connect onclick event of title to our function (just the refernce to it) */
    accordionTitle.addEventListener('click', toggle);

Last but not least, we call the toggle function two times, so the icon looks in the correct direction.

    /* Call the function two times, so the arrow looks in the right direction */


enter image description here

GitHub Repository


Excellent! You have successfully created an Accordion! See how you can add more features to this program, such as grouping them and only allowing one to be open simultaneously.

Keep in mind that I am also just a beginner, so it could be that my way of solving these problems is not the best or that I use functions or features that aren’t advised. Always ask questions and try to solve problems your way!

No Comments

No Comments Found, you Could be the First ...

Leave a Reply

Your email address will not be published. Required fields are marked *

Other Posts you may like ...

File Explorer with Vue.js

File Explorer with Vue.js

Awesome Tools and Websites

Awesome Tools and Websites

Custom Svelte Store

Custom Svelte Store

To Top
© 2022 - 2023 Maxim Maeder
Enthusiast Shui Theme Version 41