Rewriting a jQuery Accordion UI in Vanilla JS

Published 04.19.2024

Should Front-End Devs Still Use jQuery?

Recently, I needed an accordion UI for a client’s new site. The site’s CMS had an accordion module, but the look of that accordion didn’t gel with the new site design and branding. I did have the option to add some custom HTML and JavaScript, though.

I used to reach for the jQuery library for just about everything UI and UX related that I couldn’t (or didn’t) do in CSS. jQuery has nifty little show() and hide() functions that are great for accordion UIs. But the client’s new site didn’t use jQuery. Rather than load the library for one UI element, I decided to rewrite the jQuery into “vanilla” JS.

I’ve been doing this a lot with old, standby jQuery code in my sites’ files. Starting out in web development, I learned jQuery first before I ever used JS on its own. jQuery is a great library, and I still use it for some projects. But a lot of the problems jQuery was developed to solve don’t really exist in modern JavaScript. We can do a lot of what jQuery does almost as simply in JS–but with more control and without the need to load a library.

The Finished Accordion in Action

jQuery Document Ready in Vanilla JS

Starting at the top, you can change the classic jQuery document ready function here:

$(document).ready(function(){
  // your code here …
});

…into a vanilla JavaScript version:

document.addEventListener('DOMContentLoaded', function () {
  // do something here …
}, false);

Note that although the event listener is “DOMContentLoaded,” images and external resources on the page may not be fully loaded yet. But it is indicative that the DOM is ready to be manipulated.

Vanilla JS Check if Element Exists

To check if a page element exists (before trying to work with it), in jQuery I often used this:

if ($('.element').length != 0) {
  // run code
}

In plain JavaScript, we can use this instead:

let elem = document.querySelector('.elem');

if (elem) {
  // do stuff
}

The Original jQuery Accordion

Here is the core functionality of the old jQuery accordion–we target the element with the class accordion-header and reveal or hide the corresponding element with the class accordion-content using the jQuery toggle() method. toggle() checks to see if the element is visible, and then either shows or hides it:

$('.accordion-header').click(function(event){
  event.preventDefault();

  $(this, '.accordion-content').toggle();
});

The Vanilla JS Version

To do this in vanilla JS, we’ll need to write a few more lines of code, but not many. Instead of showing or hiding the .accordion-content element with built-in methods, we will toggle an active class on the element and show and hide it using CSS.

const accordionHeaders = document.querySelectorAll('.accordion-header');

accordionHeaders.forEach(function (accordionHeader, index) {
  accordionHeader.addEventListener('click', function (event) {
    event.preventDefault();
  
    accordionHeader.classList.toggle('active');
    accordionHeader.nextElementSibling.classList.toggle('active');
  });
});

First, we find the elements in the document with an accordion-header class and loop through them, adding a listener for click events on each one that toggles the active class on that element. In the HTML, the corresponding .accordion-content element (with the content we want to show or hide) is next to its .accordion-header element, like this:

<h3 class="accordion-header">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h3>
<div class="accordion-content">
  <p>Duis sed nulla quis leo pharetra luctus ac non libero. Etiam nisi eros, placerat vitae tristique sit amet, finibus sed ante. Donec vitae nunc sem. Fusce interdum quis lectus non luctus. Proin elementum, elit non ullamcorper ullamcorper, odio libero ultrices metus, in pharetra nisi augue quis lacus. Praesent ac urna urna. Nam vitae mauris viverra, iaculis risus ac, rutrum justo.</p>
</div>

So we are able to toggle the active class on the .accordion-content element as well by selecting this.nextElementSibling.

CSS for Revealing and Hiding Content

Finally, the CSS for showing and hiding the .accordion-content element:

.accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.35s ease-in-out;
}
.accordion-content.active {
  max-height: 1000px;
}

We set the max-height attribute for .accordion-content elements to 0 and also add overflow: hidden. Together this hides the content inside the element. There is also a transition animation added to the max-height attribute. When the active class is added to the element through the JavaScript, we increase the max-height to 1000px (this variable just needs to be taller than anything inside the .accordion-content elements) and the content is revealed with an animation.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Me

About Me

I'm a Senior Front-End Web Developer at Bond Digital, a digital design and marketing agency in Chicago. I live in Oak Park, IL, with my wife, Madhurima, and my son, Kunal. When I'm not building websites, I'm playing guitar, playing video games, writing, or reading.

Contact Me