How to make an Accordion Menu using HTML, CSS and Javascript.

An accordion menu is used to arrange various pieces of information vertically or horizontally as a list where the content is hidden by default and is visible after clicking the header corresponding to a specific section of the content you want to read. This is common when building FAQs pages for a website.

Vertical accordion menus are the most frequently used where each section has a header panel which upon clicking expands vertically to show its subsections.

The code below is an example of how a vertical accordion menu can be created using HTML, CSS and Javascript.

HTML

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Accordion</title>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div class="accordion">
		<div class="contentBx">
			<div class="label">Section One</div>
			<div class="content">
				<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
			</div>
		</div>
		<div class="contentBx">
			<div class="label">Section Two</div>
			<div class="content">
				<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
			</div>
		</div>
		<div class="contentBx">
			<div class="label">Section Three</div>
			<div class="content">
				<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
			</div>
		</div>

	</div>
	<script src="script.js">
</script>
</body>
</html>

CSS

.accordion{
	max-width: 800px;
}

.accordion .contentBx{
	position: relative;
	margin: 10px 20px;
}

.accordion .contentBx .label{
	position: relative;
	padding: 10px;
	background: #2694af;
	color: #ffff;
	cursor: pointer;
}

.accordion .contentBx .label::before{
	content: '+';
	position: absolute;
	top: 50%;
	right: 20px;
	transform: translateY(-50%);
	font-size: 1.5em;
}

.accordion .contentBx.active .label::before{
	content: '-';
}

.accordion .contentBx .content{
	position: relative;
	background: #fff;
	height: 0;
	overflow: hidden;
	transition: 0.5s;
	overflow-y: auto;
}

.accordion .contentBx.active .content{
	height: 150px;
	padding: 10px;
}

JS


const accordion = document.getElementsByClassName('contentBx');
		for(i = 0; i<accordion.length; i++){
           accordion[i].addEventListener('click',function(){
           	this.classList.toggle('active')
           })
		}

Output

Accordion
Section One

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Section Two

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Section Three

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

I have used the “+” icon on the section header by default which changes to “-” icon when the accordion menu opens. These icons keep on toggling depending on the state of the accordion.

Animated Accordion

From the output of the first example above, the contents of one section remain visible when another section is opened. This can at times be difficult to navigate the menu but can be improved such that only the section whose header panel is clicked is expanded to reveal its information while other sections remain collapsed.

The code below is used to achieve this animated effect.

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="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
    <div class="animaccordion">
        <div class="animaccordion-content">
            <h2>
                <span class="animaccordion-title">Section One</span>
                <i class="fas fa-plus"></i>
            </h2>

            <p class="animaccordion-description">
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus nobis ut perspiciatis minima quidem nisi, obcaecati, delectus consequatur fuga nostrum iusto ipsam ducimus quibusdam possimus. Maiores non enim numquam voluptatem?
            </p>
        </div>

        <div class="animaccordion-content">
            <h2>
                <span class="animaccordion-title">Section Two</span>
                <i class="fas fa-plus"></i>
            </h2>

            <p class="animaccordion-description">
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus nobis ut perspiciatis minima quidem nisi, obcaecati, delectus consequatur fuga nostrum iusto ipsam ducimus quibusdam possimus. Maiores non enim numquam voluptatem?
            </p>
        </div>
        <div class="animaccordion-content">
            <h2>
                <span class="animaccordion-title">Section Three</span>
                <i class="fas fa-plus"></i>
            </h2>

            <p class="animaccordion-description">
                Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus nobis ut perspiciatis minima quidem nisi, obcaecati, delectus consequatur fuga nostrum iusto ipsam ducimus quibusdam possimus. Maiores non enim numquam voluptatem?
                Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto neque, sed inventore illum ut quis ducimus deleniti temporibus maiores? At nisi sed pariatur cupiditate quidem quod adipisci aut, eos quis minima voluptates non veniam ipsam quasi architecto ducimus error eum id ab, suscipit doloribus, ut accusantium consequuntur voluptate! Unde, hic sed rerum officia totam id libero officiis nihil rem sequi porro labore praesentium repudiandae a blanditiis molestias nisi beatae natus! Ea, ut voluptates, natus harum nesciunt odio hic eveniet reprehenderit veritatis, possimus tempora magni soluta eaque quidem neque maxime nostrum sapiente commodi? Earum ex cumque cupiditate dicta, tempora temporibus quaerat.
            </p>
        </div>
        
    </div>
    
    <script src="script.js"></script>
</body>
</html>

CSS

.animaccordion{
    max-width: 530px;
    width: 100%;
    background: #FFF;
    margin: 0 15px;
    padding: 15px;
    border-radius: 8px;
    box-shadow:  0 0 4px rgba(0,0,0,0.2);
}
.animaccordion .animaccordion-content{
    margin: 10px 0;
    border-radius: 4px;
    background: #FFF7F0;
    border: 1px solid #FFD6B3;
    overflow: hidden;
}
.animaccordion-content:nth-child(2){
    background-color: #F0FAFF;
    border-color: #CCEEFF;
}
.animaccordion-content:nth-child(3){
    background-color: #FFF0F3;
    border-color: #FFCCD6;
}
.animaccordion-content:nth-child(4){
    background-color: #F0F0FF;
    border-color: #CCCCFF;
}
.animaccordion-content.animopen{
    padding-bottom: 10px;
}
.animaccordion-content h2{
    display: flex;
    min-height: 50px;
    padding: 0 15px;
    cursor: pointer;
    align-items: center;
    justify-content: space-between;
    transition: all 0.2s linear;
}
.animaccordion-content.animopen h2{
    min-height: 35px;
}
.animaccordion-content h2 .animaccordion-title{
    font-size: 14px;
    font-weight: 500;
    color: #333;
}
.animaccordion-content h2 i{
    font-size: 15px;
    color: #333;
}
.animaccordion-content .animaccordion-description{
    height: 0;
    font-size: 12px;
    color: #333;
    font-weight: 400;
    padding: 0 15px;
    transition: all 0.2s linear;
}

JS


const accordionContent = document.querySelectorAll(".animaccordion-content");

accordionContent.forEach((item, index) => {
    let header = item.querySelector("h2");
    header.addEventListener("click", () =>{
        item.classList.toggle("animopen");

        let description = item.querySelector(".animaccordion-description");
        if(item.classList.contains("animopen")){
            description.style.height = `${description.scrollHeight}px`; 
            item.querySelector("i").classList.replace("fa-plus", "fa-minus");
        }else{
            description.style.height = "0px";
            item.querySelector("i").classList.replace("fa-minus", "fa-plus");
        }
        removeOpen(index); 
    })
})

function removeOpen(index1){
    accordionContent.forEach((item2, index2) => {
        if(index1 != index2){
            item2.classList.remove("animopen");

            let des = item2.querySelector(".animaccordion-description");
            des.style.height = "0px";
            item2.querySelector("i").classList.replace("fa-minus", "fa-plus");
        }
    })
}

Output

Section One

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus nobis ut perspiciatis minima quidem nisi, obcaecati, delectus consequatur fuga nostrum iusto ipsam ducimus quibusdam possimus. Maiores non enim numquam voluptatem?

Section Two

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus nobis ut perspiciatis minima quidem nisi, obcaecati, delectus consequatur fuga nostrum iusto ipsam ducimus quibusdam possimus. Maiores non enim numquam voluptatem?

Section Three

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Natus nobis ut perspiciatis minima quidem nisi, obcaecati, delectus consequatur fuga nostrum iusto ipsam ducimus quibusdam possimus. Maiores non enim numquam voluptatem? Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto neque, sed inventore illum ut quis ducimus deleniti temporibus maiores? At nisi sed pariatur cupiditate quidem quod adipisci aut, eos quis minima voluptates non veniam ipsam quasi architecto ducimus error eum id ab, suscipit doloribus, ut accusantium consequuntur voluptate! Unde, hic sed rerum officia totam id libero officiis nihil rem sequi porro labore praesentium repudiandae a blanditiis molestias nisi beatae natus! Ea, ut voluptates, natus harum nesciunt odio hic eveniet reprehenderit veritatis, possimus tempora magni soluta eaque quidem neque maxime nostrum sapiente commodi? Earum ex cumque cupiditate dicta, tempora temporibus quaerat.

From the output above, you can observe that when one section header is clicked it is expanded, while other sections are collapsed.