The theme for week #13 of the Weekly Coding Challenge is:
Accordion
Hide and show content with just a click - this is what an accordion let us do. 😃
In this article we’re going to build this Accordion:
https://codepen.io/FlorinPop17/pen/PvvZmN/
The HTML
For the HTML structure we’ll use an ul
with a few li
’s (or the accordion-item
s) containing the header (h3
) and the content (p
) with some dummy lorem text:
<ul class="accordion">
<li class="accordion-item open">
<h3>First accordion item</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet,
provident.
</p>
</li>
<li class="accordion-item">
<h3>Second accordion item</h3>
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Ex autem
praesentium vitae dolores est eius officia aspernatur vero
recusandae tempora!
</p>
</li>
<li class="accordion-item">
<h3>Third accordion item</h3>
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Omnis
asperiores officia cupiditate, officiis vel aliquid eum quidem,
nostrum nihil hic repellendus dolorem facilis consequatur doloribus.
</p>
</li>
<li class="accordion-item">
<h3>Forth accordion item</h3>
<p>
Lorem ipsum dolor sit amet.
</p>
</li>
<li class="accordion-item">
<h3>Fifth accordion item</h3>
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores
saepe, pariatur earum sunt fugit reprehenderit eum provident
accusantium eos perspiciatis deserunt sed voluptates autem cumque
natus vel non nemo tenetur, perferendis repellat. Dolore eaque sed
rerum alias. Necessitatibus illo, saepe voluptate, modi dolorum
voluptates rem aspernatur, ipsum alias libero facere.
</p>
</li>
</ul>
As you can see, by default the first .accordion-item
is .open
ed. You’ll see in a moment what this does in the CSS. 🙂
The CSS
First, let’s style the .accordion
and its item
s:
.accordion {
border-radius: 4px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
list-style-type: none;
padding: 0;
overflow: hidden;
}
.accordion-item {
background-color: #fff;
cursor: pointer;
width: 400px;
}
This will create a fixed width accordion of 400px
.
Next, let’s style the header:
.accordion-item h3 {
color: #fff;
font-weight: 400;
letter-spacing: 0.4px;
margin: 0;
padding: 20px 15px;
position: relative;
}
As you can see, it has a relative
position and this is because we want to add a small down pointing arrow within it using the ::after
selector and a fontawesome icon:
.accordion-item h3::after {
content: '\f078';
font-family: 'Font Awesome 5 Free';
font-weight: bold;
position: absolute;
top: 50%;
right: 15px;
transform: translateY(-50%) rotate(0);
transition: transform 0.3s ease-in-out;
}
.accordion-item.open h3::after {
transform: translateY(-50%) rotate(180deg);
}
We need to specify the font-family
property and the desired icon (\f078
in our case) in order for it to show up. Also, let’s rotate
the icon 180deg when the accordion item is .open
ed.
Great! Next, we’ll add the “gradient-like” effect on the accordion-items. For this we are going to target each separate item and apply a different background-color
:
.accordion-item:nth-child(1) h3 {
background-color: #fd79a8;
}
.accordion-item:nth-child(2) h3 {
background-color: #f76ba2;
}
.accordion-item:nth-child(3) h3 {
background-color: #f25e9d;
}
.accordion-item:nth-child(4) h3 {
background-color: #ed5098;
}
.accordion-item:nth-child(5) h3 {
background-color: #e84393;
}
Kind of old fashion as we could do it more dynamically, but for now it should do the job! (Note that if you have more than 5 items, you need to color them individually 😅).
Next, let’s style the content (or the p
in our case):
.accordion-item p {
display: none;
letter-spacing: 1px;
margin: 0;
padding: 15px;
text-align: justify;
}
.accordion-item.open p {
display: block;
}
As you can see the text is only displayed when the accordion is .open
ed.
I’ve chose to use just a simple p
tag in this case, but you can add here multiple tags and contents and even create a multiple level accordion if you want. 😃
The JavaScript
And at the end, let’s add a little bit of functionality.
For that we need to target all the .accordion-item
s and we’ll add a click eventListener: Every time one item is clicked we’ll do the following:
- Check if the corresponding item is already opened by checking if it has the
.open
class:- if it is, close it by removing that class
- if it isn’t, remove the
.open
class from all theaccordion_item
s and add it only to the clicked one
const accordion_items = document.querySelectorAll('.accordion-item');
accordion_items.forEach(elem =>
elem.addEventListener('click', () => {
if (elem.classList.contains('open')) {
elem.classList.remove('open');
} else {
accordion_items.forEach(elem2 => elem2.classList.remove('open'));
elem.classList.add('open');
}
})
);
Conclusion
You can go one step further and add a little bit of animation when the .accordion-item
is closed and opened.
I’m very curious to see what other functionalities you’ll add to this simple component! Have fun! 😄
Happy Coding! 😇