In today’s tutorial we’ll learn how to build a show/hide component with CSS and a little bit of JavaScript. By default, jQuery provides the slideToggle
method which allows us to create accordions with a sliding motion. Our challenge is to mimic this functionality with pure JavaScript.
Here’s the component we’ll be creating:
1. The HTML
To begin with, we define an element with the class of container
which contains two sub-elements:
- the button which will hide and reveal the content (including an inline SVG icon)
- the actual content
Here’s what that looks like:
<div class="container"> <!-- other content here --> <button class="toggle-btn"> <span class="more show"> Show More info <svg width="24" height="24" viewBox="0 0 24 24"> <path d="M0 7.33l2.829-2.83 9.175 9.339 9.167-9.339 2.829 2.83-11.996 12.17z"/> </svg> </span> <span class="less hide"> Show Less info <svg width="24" height="24" viewBox="0 0 24 24"> <path d="M0 16.67l2.829 2.83 9.175-9.339 9.167 9.339 2.829-2.83-11.996-12.17z"/> </svg> </span> </button> <div class="info"> <!-- content here --> </div> <!-- other content here --> </div>
2. The CSS
The CSS is pretty straightforward. We need to define two helper classes (i.e. hide
and show
).
To hide and reveal the target element, we’ll use the height
property, but we won’t specify its values in CSS. Instead, we’ll dynamically set the height values through JavaScript.
One thing to note is that we don’t use the display
property for toggling the visibility of our content. That property doesn’t count itself among the animatable CSS properties.
Here are the corresponding CSS styles:
.hide { display: none; } .show { display: flex; } .info { overflow: hidden; transition: height .5s; }
3. The JavaScript
Now it’s time to discuss how our JavaScript code should work.
First, as soon as the DOM is ready, we get the height of the .info
element and then immediately set its value to 0.
const info = document.querySelector(".info"); let infoHeight = info.offsetHeight; info.style.height = 0;
Keep in mind that depending on your content (e.g. if it includes images) you might have to enclose the code above inside the load
event.
Next, when the .toggle-btn
button is clicked we do the following:
- Toggle the visibility of the
.less
and.more
elements. - Recalculate the height of the
.info
element. If it’s 0 (initially we give it this value), that means the content is hidden, so we reveal it by setting its height equal to its initial height (stored in theinfoHeight
variable). On the other hand if the content is visible, we hide it by setting its height to 0. - Optionally, we ensure that the
.toggle-btn
will be clicked only once until the slide animation finishes (it lasts 500 ms).
Here’s the code that implements all that behavior:
const toggleBtn = document.querySelector(".toggle-btn"); const info = document.querySelector(".info"); const less = document.querySelector(".less"); const more = document.querySelector(".more"); // initial height let infoHeight = info.offsetHeight; toggleBtn.addEventListener("click", function() { this.disabled = true; more.classList.toggle("show"); more.classList.toggle("hide"); less.classList.toggle("show"); less.classList.toggle("hide"); const infoNewHeight = info.offsetHeight; if(infoNewHeight == 0) { info.style.height = `${infoHeight}px`; } else { info.style.height = 0; } setTimeout(() => { this.disabled = false; }, 500); });
Browser Resize
The next step is to ensure that the component will work correctly as the browser window gets resized.
Here’s the necessary JS code:
// variable definitions here window.addEventListener("resize", () => { info.style.removeProperty("height"); infoHeight = info.offsetHeight; if(more.classList.contains("hide")) { info.style.height = `${infoHeight}px`; } else { info.style.height = 0; } });
4. Browser Support
Our demo should work well in all recent browsers and devices. Also, as usual, we use Babel to compile the ES6 code down to ES5.
Conclusion
In this short tutorial we built an accordion-style show/hide component with CSS and JavaScript. Thanks to the animatable height
property, we managed to add a slide-in/slide-out effect to our component.
Notably, we haven’t considered accessibility, so if you want to enhance its functionality that certainly could be the next step.
More Tutorials “With a Touch of JavaScript”
-
JavaScriptHow to Build a Responsive Tab Component With CSS and a Touch of JavaScript
-
Navigation DesignHow to Build an Off-Canvas Menu With CSS and a Touch of JavaScript
-
JavaScriptA Simple JavaScript Technique for Filling Star Ratings
-
Navigation DesignHow to Build a Shifting Underline Hover Effect With CSS and JavaScript
No comments:
Post a Comment