DEV Community

Shameer Chagani
Shameer Chagani

Posted on

How to create Bootstrap like Accordions using HTML | CSS | JavaScript

what's up guys!
Hope you all are doing well.
In most of my small projects I try to keep away from using libraries for CSS/JavaScript as much as possible, reason being it offers me more control over my code. I've seen many developers using tools/libraries for even a small things, Am not against using them It just depends on one's personal choice.
Today I want to talk about a way to create Accordions using plain JavaScript. Its simpler than you think. so lets dive in.

  • First Create a folder named accordions.(You can name it as you want but i like to keep it simple).
  • inside of this accordions Folder create two more folders css and js and a file index.html.
  • Let's now create two more files style.css inside of css folder and script.js inside of js folder. our file and folder structure is all set.

let begin with index.html

<!DOCTYPE html>
 <html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="css/style.css" />

  <title>Accordions</title>
</head>
<body>
  <header>
    <h1>Accordions using HTML CSS and JavaScript.
  </header>
    <main>      
    <section class="container">

    </section>
    </main>
</body>
<script src="js/script.js"></script>
</html>
Enter fullscreen mode Exit fullscreen mode

The above is just basic boilerplate for our project we have linked our stylesheets and javascript files and added fontawesome cdn link for icons in the html and added a heading.

  • Now I want to create 3 sections inside of the section with class container, and give it a class accordions.
  • And inside of these each sections I want to create another section with the class heading which will hold our div element with class text and another div with the class icon, which will be our heading of the accordion.
  • And finally create one more section inside of the section with class accordion and give it a class of definition.

Our code will look something like this.

<section class="accordion active">
        <section class="heading">
          <div class="text">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio, earum!
          </div>
          <div class="icon">
            <i class="fa fa-caret-down" aria-hidden="true"></i> 
          </div>
        </section>
        <section class="definition">
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Expedita laboriosam, natus atque laudantium iure delectus, sapiente deleniti optio dolorum officiis a vero dicta corrupti assumenda accusamus, fugit et aspernatur sequi dolores recusandae. Expedita, tempora quam dicta dolores voluptatum, quasi temporibus, reiciendis laudantium incidunt exercitationem possimus perspiciatis. Reiciendis beatae dolor ex neque, eum nesciunt sunt nisi deserunt, doloribus tempore ipsa commodi. Ducimus quam, accusamus provident quisquam asperiores dolor illum expedita odit. Quia quas neque deserunt, odit libero ab dolorem iste, error est rem dolorum, voluptates incidunt optio architecto. Consequuntur incidunt facilis optio rem suscipit porro, tenetur, animi maxime aliquam modi ex!
       </section>
</section>

<section class="accordion active">
        <section class="heading">
          <div class="text">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio, earum!
          </div>
          <div class="icon">
            <i class="fa fa-caret-down" aria-hidden="true"></i> 
          </div>
        </section>
        <section class="definition">
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Expedita laboriosam, natus atque laudantium iure delectus, sapiente deleniti optio dolorum officiis a vero dicta corrupti assumenda accusamus, fugit et aspernatur sequi dolores recusandae. Expedita, tempora quam dicta dolores voluptatum, quasi temporibus, reiciendis laudantium incidunt exercitationem possimus perspiciatis. Reiciendis beatae dolor ex neque, eum nesciunt sunt nisi deserunt, doloribus tempore ipsa commodi. Ducimus quam, accusamus provident quisquam asperiores dolor illum expedita odit. Quia quas neque deserunt, odit libero ab dolorem iste, error est rem dolorum, voluptates incidunt optio architecto. Consequuntur incidunt facilis optio rem suscipit porro, tenetur, animi maxime aliquam modi ex!
       </section>
</section>    

<section class="accordion active">
        <section class="heading">
          <div class="text">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio, earum!
          </div>
          <div class="icon">
            <i class="fa fa-caret-down" aria-hidden="true"></i> 
          </div>
        </section>
        <section class="definition">
           Lorem ipsum dolor sit amet, consectetur adipisicing elit. Expedita laboriosam, natus atque laudantium iure delectus, sapiente deleniti optio dolorum officiis a vero dicta corrupti assumenda accusamus, fugit et aspernatur sequi dolores recusandae. Expedita, tempora quam dicta dolores voluptatum, quasi temporibus, reiciendis laudantium incidunt exercitationem possimus perspiciatis. Reiciendis beatae dolor ex neque, eum nesciunt sunt nisi deserunt, doloribus tempore ipsa commodi. Ducimus quam, accusamus provident quisquam asperiores dolor illum expedita odit. Quia quas neque deserunt, odit libero ab dolorem iste, error est rem dolorum, voluptates incidunt optio architecto. Consequuntur incidunt facilis optio rem suscipit porro, tenetur, animi maxime aliquam modi ex!
       </section>
</section>        
Enter fullscreen mode Exit fullscreen mode

I hope its clear now. lets get to the styling part.

in our style.css paste the following code.

@import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}
header h1 {
  background: coral;
  color: #fff;
  text-align: center;
  padding: 10px;
}
body {
  background: #f6f6f6;
}
main {
  width: 90%;
  min-height: calc(100vh - 90px);
  margin: 10px auto;
  background: #fff;
  box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
}
main section.container {
  padding: 15px 25px;
}
h3 {
  margin-top: 10px;
}
section.accordion {
  margin-top: 10px;
}
section.accordion .heading {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: coral;
  padding: 10px;
  cursor: pointer;
}
section.accordion .heading div.text {
  flex: 10;
  font-weight: 600;
}
section.accordion .heading div.icon {
  flex: 1;
  text-align: center;
}
section.accordion.active .heading,
section.acordion.active .icon {
  color: #fff;
}
section.accordion .heading div.icon i {
  font-size: 1.5em;
  cursor: pointer;
}
section.accordion.active .definition {
  display: block;
  transition: display 0.3s ease-in;
}
section.accordion .definition {
  display: none;
  padding: 10px;
  transition: display 1s ease-in-out;
}
Enter fullscreen mode Exit fullscreen mode

Now open index.html in your browser it should look like below

Image description

lets open our script.js and start writing some JavaScript code.


let accIcons = document.querySelectorAll(".accordion .icon i")

accIcons.forEach((accIcon) => {
  addEventListener("click", expand)
})

function expand(e) {  e.target.parentNode.parentNode.parentNode.classList.toggle("active");
}

Enter fullscreen mode Exit fullscreen mode

lets try to understand the code.

  • in the first line we are grabbing all the icons and placing them in a vairable accIcons .
  • in the second line we are adding a click event to all the icons which will when clicked run a function named expand
  • this function will toggle the active class on the targeted accordion. And this event will be fired whenever we click caret-down icon.

I want to add 2 more functionalities to these.

  1. Collapse all
  2. expand all

let open our index.html create 2 buttons and add some stylings

in the container below <h3> write the below code.

<div class="btns">
   <button class="collapseAll" id="collapseAll"> 
       Collapse All
   </button>
   <button class="expandAll" id="expandAll">
       Expand All
   </button>
</div>

Enter fullscreen mode Exit fullscreen mode

lets style them

div.btns {
  margin-top: 20px;
  text-align: center;
}
button {
  padding: 2px 7px;
  cursor: pointer;
  border-radius: 15px;
  font-size: 0.75em;
  outline: none;
  border: 0.5px solid black;
}
button#collapseAll {
  background: cyan;
}
button#expandAll {
  background: firebrick;
  color: #f3f3f3;
}
Enter fullscreen mode Exit fullscreen mode

our webpage should look like this now:
Image description

When i click collapse all button all the accordions should collapse.
and when i click expand all button all the accordions should expand.
so lets write the code in our script.js

let accordions = document.querySelectorAll(".accordion");
let expandBtn = document.querySelector("#expandAll");
let collapseBtn = document.querySelector("#collapseAll");

expandBtn.addEventListener("click", expandAll);
collapseBtn.addEventListener("click", collapseAll);

function collapseAll() {
  accordions.forEach((accordion) => {
    accordion.classList.remove("active");
  });
}

function expandAll() {
  accordions.forEach((accordion) => {
    accordion.classList.add("active");
  });
}

Enter fullscreen mode Exit fullscreen mode

lets understand whats happening here.
we are grabbing all the accordions with the class accordion and placing them in accordions
next we are grabbing the two buttons we just created and placing them in collapseBtn and expandBtn;
Then we are adding a click even for each of this buttons. which then will run different functions.

When we click on collapseBtn it will run function collapseAll, which will collapse all the accordions with className accordion we achieve this by classList.remove() method.

when we click on expandBtn it wil run function expandAll, which will expand all the accordions with className accordion we achieve this by classList.add() method.

The link to the codepen is below, which has the full code. if you have any doubts or any questions please feel free to post them in the discussion below.
If you liked this post please like and follow me for more cool stuffs like this.

Link: https://codepen.io/shameerchagani/full/vYpZZqL

Cheers!!

Top comments (2)

Collapse
 
gcosgreaveus profile image
Gavin Cosgreave

Accessibility wise this isnt a great solution. The whole accordion item should be clickable IMO. Nice work apart from that.

Collapse
 
shameerchagani profile image
Shameer Chagani

Agreed!