A simple Accordion Menu Using HTML, CSS and JavaScript.
Tags: html, css, javascript
Published: 2020-06-23 15:08:36

Hey awesome devs. Let's have a look at how we can create a simple accordion menu using HTML, CSS and just a few lines of JavaScript. Let's get started with the HTML.

First, create a div with the class of `container`
```HTML
<div class="container">
</div>
```
Within this `div`, let's add a paragraph and give it a class of `title`.
```HTML
<div class="container">
<p class="title">Do you accept online payements?</p>
</div>
```
Also, within the same `container` div, add another paragraph and give it a class of `content`. Fill this paragraph with some dummy text.

Copy the above two `paragraph` tags, and paste them two more times, so that you have 3 pairs of `paragraph` tags.

Finally, inside our `paragraphs` with the class of `title`, add a `span` tag, which contains a `+` sign . This sign will change to `-` when clicked by the user on the corresponding title. Below is what your `HTML` code should look like by now.

```HTML
<div class="container">
  <p class="title">Do you accept online payements?<span>+</span></p>
  <p class="content">Lorem ipsum dolor, sit amet consectetur 
  adipisicing elit....</p>
  <p class="title">Do you have a return policy?<span>+</span></p>
  <p class="content">Lorem ipsum dolor, sit amet consectetur 
  adipisicing elit....</p>
  <p class="title">What is the average delivery time?<span>+</span></p>
  <p class="content">Lorem ipsum dolor, sit amet consectetur 
  adipisicing elit....</p>
</div>
```

And that's all we need for the HTML. Now, let's get started with the CSS by first adding some basic reset.

``` CSS
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
```
Add the below styles to the `body` and the div with the class of `container`.
``` CSS
body{
  background-color: #2BBA9E;
  font-family: Verdana;
}

.container{
  width: 80%;
  margin: 0 auto;
  background-color: #fff;
  margin-top: 10%;
}
```

Add styles to the paragraphs which have the class of `title` and `content`
```CSS
.title{
  background-color: #202D3C;
  padding: .8rem;
  border-bottom: 1px solid #000;
  cursor: pointer;
  position: relative;
  user-select: none;
  color: #fff;
  letter-spacing: .1rem;
}

.content{
  padding: 1rem;
  line-height: 1.5rem;
  display: none;
}
```
In the above code, notice that we have given `display: none` to the paragraphs with the class of `content`. Now, all you can see are the titles of the accordion menu. Later we will be changing the `display` to `block` using a class, which will be added with the help of JavaScript. 

At last, we need to style the `span` which contains the `+` sign.
```CSS
span{
  position: absolute;
  right: 1rem;
}
```
And this is what we have so far.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cgcnv4y23wtm3i3zruwn.jpg)

Now, it's time to move to the most crucial part, the JavaScript. 
First select all the paragraphs with the class of `title` and save these to a variable.
```javascript
let title = document.querySelectorAll(".title");
```
Let's use a `for loop` to loop over each of these.
```javascript
for(let i = 0; i < title.length; i++){
}
```
Add an event listener of `click` to each of them.
```javascript
for(let i = 0; i < title.length; i++){
title[i].addEventListener("click", function(){
 })
}
```
Now, we need to select the specific `content`, which corresponds to the `title` that the user clicks. For this, we will be using the `nextElementSibling` property. So, here's what it would look like.
`this.nextElementSibling`

Of course, understanding the `this` keyword can be a bit tricky. But, just keep in mind that in this case, the `this` keyword refers to the `title` that the user clicks on.

Let's save the above line of code to a variable named `result`. And, here's the code we have so far.
  ```javascript
for(let i = 0; i < title.length; i++){
title[i].addEventListener("click", function(){
  let result = this.nextElementSibling;
 })
}
```
For our accordion to work, we just need one more line of code. Remember we had given the paragraphs with the class of `content` a display of 'none'? Well, it's time to change the display to `block` when the user clicks on a corresponding `title`.

Create a CSS class of `active` and add a single property of `display: block`.
 ```CSS
.active{
  display: block;
}
```
Using the `classList` property, let's add the `active` class to paragraphs with the class of `content`, so that it is displayed as `block`. However, when the user clicks on it again, we want to change the display back to `none`. So, we will be using `classList.toggle`.

```javascript
for(let i = 0; i < title.length; i++){
  title[i].addEventListener("click", function(){
    let result = this.nextElementSibling;
    result.classList.toggle("active");
  })
}
```
And we are almost done. The only thing that we need to work on now is the `span` which contains the `+` sign. The idea is simple. The `+` sign will be shown when the `content` is hidden, and will be replaced with a `-` sign when the content is shown. We can use the `if statement` to do the same.

So, our final JavaScript code will look like.
```javascript
let title = document.querySelectorAll(".title");

for(let i = 0; i < title.length; i++){
  title[i].addEventListener("click", function(){
    let result = this.nextElementSibling;
    result.classList.toggle("active");
    
     if(this.firstElementChild.innerText === "+"){
       this.firstElementChild.innerText = "-"
       }
    else{
      this.firstElementChild.innerText = "+"
    }
   
  })
}
```
 And that's how you create a simple accordion menu using HTML, CSS and just a little bit of JavaScript. Hope you like it.