DEV Community

Cover image for Content Organization with Animated FAQ Accordion in 2021 !🔥|| CSS JS
Joy Shaheb
Joy Shaheb

Posted on • Edited on

Content Organization with Animated FAQ Accordion in 2021 !🔥|| CSS JS

If Users can't find what they want in a website in the First 3 Seconds, then they're Leaving.

In order to prevent this misfortune, we can organize our FAQ/contents in an Animated Accordion. Like this one below 👇

This Blog is About Building A FAQ Accordion in 2021 using CSS & JS. So, Let's start the Journey 💪

Codepen 🔥

You can find the full code on Codepen

Youtube Tutorial 🔥

If this post is difficult for you then see Step by step Tutorial on Youtube 🔥

Table Of Contents 🔥

HTML :

We're gonna create 4 div inside a parent div with class name container. Let's start small with 1 item.
Like this 👇

<div class="container">
  <h1>Frequently Asked Questions</h1>

  <div class = "item-1">  </div>

</div>

Enter fullscreen mode Exit fullscreen mode

Next up, setup 2 siblings with class-name .accordion & .panel inside .item-1 class

<div class="container">
  <h1>Frequently Asked Questions</h1>

  <div class = "item-1">
    <div class="accordion">  </div>
    <div class="panel">  </div>
  </div>

</div>

Enter fullscreen mode Exit fullscreen mode

Inside .accordion, create 2 siblings- .title & .icon
Inside .icon, write "+"
Inside .title, write your content, *anything u wish.
Inside .panel, set some dummy text.

<div class="container">
  <h1>Frequently Asked Questions</h1>

  <div class = "item-1">
    <div class="accordion">
      <div class="title">How to Install?</div>
      <div class="icon">+</div>
    </div>
    <div class="panel">
       <p>
         Lorem ipsum dolor sit amet consectetur adipisicing elit. 
         Rem commodi provident modi eligendi consequuntur esse 
         consequatur quis corrupti delectus quas.
       </p>
    </div>
  </div>

</div>

Enter fullscreen mode Exit fullscreen mode

Like this, create 4 sibling div, and end up the HTML Part.

<div class="container">
  <h1>Frequently Asked Questions</h1>

  <div class="item-1">
    <div class="accordion">
      <div class="title">How To Install ?</div>
      <div class="icon">+</div>
    </div>
    <div class="panel">
      <p>
         Lorem ipsum dolor sit amet consectetur adipisicing elit. 
         Rem commodi provident modi eligendi consequuntur esse 
         consequatur quis corrupti delectus quas.
      </p>
    </div>
  </div>


  <div class="item-2">
    <div class="accordion">
      <div class="title">How To Uninstall ?</div>
      <div class="icon">+</div>
    </div>
    <div class="panel">
      <p>
         Lorem ipsum dolor sit amet consectetur adipisicing elit. 
         Rem commodi provident modi eligendi consequuntur esse 
         consequatur quis corrupti delectus quas.
      </p>
    </div>
  </div>


  <div class="item-3">
    <div class="accordion">
      <div class="title">How To Upgrade ?</div>
      <div class="icon">+</div>
    </div>
    <div class="panel">
      <p>
         Lorem ipsum dolor sit amet consectetur adipisicing elit. 
         Rem commodi provident modi eligendi consequuntur esse 
         consequatur quis corrupti delectus quas.
      </p>
    </div>
  </div>


  <div class="item-4">
    <div class="accordion">
      <div class="title">Refund Policy ?</div>
      <div class="icon">+</div>
    </div>
    <div class="panel">
      <p>
         Lorem ipsum dolor sit amet consectetur adipisicing elit. 
         Rem commodi provident modi eligendi consequuntur esse 
         consequatur quis corrupti delectus quas.
      </p>
    </div>
  </div>


</div>

Enter fullscreen mode Exit fullscreen mode

Rules Setup :

In this part,
We're gonna pick "Poppins" as the font-family,
Create a template using a mixin,
Create some commonly used variables, and
Change default styles by the * selector.


@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');

//*** Template of the CSS Flexbox Model******

@mixin flex($jus,$ali){
  display: flex;
  justify-content:$jus;
  align-items:$ali;
}

// Commonly used Values/colors as variables

$bgc: #000;
$color-1: #fff;
$color-2: red;

*{
  margin:0px;
  padding:0px;
  box-sizing:border-box;
  body{
    @include flex(center,null);
    width:100%;
    min-height:100vh;
    background-color: $bgc;
    color: $color-1;
    font-family: 'Poppins';
  }
}

Enter fullscreen mode Exit fullscreen mode

SCSS :

First, style the .container

.container{
  width:80%;

  //***Media Query to make the Accordion look good on larger screens.

  @media (min-width: 800px){
    width:45%;
  }

  h1{
    text-align:center;
    font-weight:300;
    margin: 50px 0;
  }
}

Enter fullscreen mode Exit fullscreen mode

Then, style the .accordion

// Targetting & styling all .accordion classes

.accordion{
  @include flex(space-between,null);
  border-bottom: 2px solid $color-2;
  font-size: 22px;
  letter-spacing: 5px;
  // text-transform: uppercase;
  font-weight: 500;
  cursor:pointer;
  transition: all .3s ease;
  &:hover{
    color: $color-2;
  }
}

Enter fullscreen mode Exit fullscreen mode

Next up, style the .panel

// Targetting & styling all .panel classes

.panel{
  max-height: 0px;
  overflow:hidden;
  transition: all 1s ease;
  p{
    margin: 10px 0px 10px 20px;
    text-align:justify;
  }
}

Enter fullscreen mode Exit fullscreen mode

Finally, create an extra .open class to be used in JS

// This is an extra class. It will be used inside javascript.
// it's main task is to change color of accordion title from white to red.

.open{
  color : $color-2;
}
Enter fullscreen mode Exit fullscreen mode

JavaScript :

Explanation is given as comments on the code. If you don't understand this part, then scroll to top, and see the youtube tutorial.


// Targetting all the .accordion classes
let acc = document.getElementsByClassName('accordion')

// console.log(acc);

// Creating a loop to add eventListener to all .accordion classes

for(let i=0;i<acc.length;i++){
  acc[i].addEventListener('click',function(){


//targetting sibling of every .accordion class named .panel class

    let panel = this.nextElementSibling

//if panel is open, then this block will close it on mouse click

    if(panel.style.maxHeight){
      panel.style.maxHeight=null;
      this.classList.remove('open')
      this.getElementsByClassName('icon')[0].innerHTML ='+';
    }
 //if panel is closed, then this block will open it on mouse click
    else{

//Removes everthing on previous accordion on new mouse click       
//by this for loop

      for(let x=0;x<acc.length; x++){
        acc[x].classList.remove('open')
        acc[x].nextElementSibling.style.maxHeight=null;
        acc[x].getElementsByClassName('icon')[0].innerHTML ='+';

      }

 //if panel is closed, then these codes will open it on mouse click & set those specific rules mentioned below.

      panel.style.maxHeight = panel.scrollHeight + 'px';
      this.classList.toggle('open')
      this.getElementsByClassName('icon')[0].innerHTML ='-'
    }
  })
}

Enter fullscreen mode Exit fullscreen mode

Once Again, if this post is difficult for you then see Step by step Tutorial on Youtube 🔥

Conclusion :

Congratulations 🎖️

We're done with the project. 🔥
Let me Know your Thoughts on the Comment Box.

Suggestions & Criticisms are Highly Appreciated ❤️️

Top comments (0)