Vanilla javascript slideToggle

One of the most useful functions jQuery offers is slideToggle or slideUp/slideDown. As developers are tending to move away from jQuery for performance reasons or simply because it’s fallen out of fashion it can be a little challenging filling some of those gaps that jQuery filled so easily. Let’s take a look at how to replicate one of jQuery’s most used features with plain Javascript and a little CSS.

Let’s start by looking at the structure of the HTML. We start with a container div with the class of .slideToggle, this is the entry point for our Javascript to work from. Then we have a button and an unordered list. These elements can be whatever you want but the first element should always be some kind of clickable element like a button, link, or image and the second element should always be a container for the elements that you would like to reveal on click.

<div class="slideToggle">
    <button>Slide Down</button>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>
</div>

The CSS is quite simple but it’s really what makes this all work. Overflow-y makes sure that we are able to set our height to 0 and to make sure that when we reveal our slide content it appears as though it’s being revealed. Without overflow it would appear like our content has been squished and distorted in a small container. Lastly if we want to animate the slide(I’m assuming you do) we add a transition to make our height change smooth.

Note: If you would like to do a slide up, set your height to 100% here. See the CodePen example below.

.slideToggle ul {
    overflow-y: hidden;
    height: 0px;
    transition: all 0.3s;
}

Last but not least, we have our Javascript. I won’t go line by line here but the premise is that we want to set the height of our content container(ul in this case) so that it expands to show all the items inside. For our CSS transition to work properly though we need to set a fixed px height, so we find the items in the content container, get their heights, add them up and then apply the total height to the content container.

This code will find any instance of .slideToggle and apply the functionality to it. This works with any number of slideToggles on a page.

const slideToggle = document.querySelectorAll(".slideToggle");
// loop over each slideToggle instance
slideToggle.forEach(function (s) {
	// select the first child / our clickable element
	const btn = s.querySelector("*");
	btn.addEventListener("click", function () {
		const itemsContainer = this.nextElementSibling;
		// if the itemsContainer is open close it
		if (itemsContainer.getBoundingClientRect().height > 0) {
			itemsContainer.style.height = "0px";
		} else {
			const items = itemsContainer.children;
			let h = 0;
			// get the height of each item
			[...items].forEach(function (item) {
				h = h + item.getBoundingClientRect().height;
			});
			itemsContainer.style.height = h + "px";
		}
	});
});

See the Pen Vanilla Javascript slideToggle by Craig Melville (@acekreations) on CodePen.

And now we have a replacement for jQuery slideToggle! This example has been purposefully made to be versatile but could be tightened up a bit if you wanted to make your HTML a bit more verbose. It’s also worth noting that if you add padding or margin to the slide content container(ul in this case) it can cause some issues, I would recommend adding padding to the content items if possible.