DEV Community

Bruno Vieira
Bruno Vieira

Posted on

20 3

Vanilla JS SlideDown/Up

Hey Guys,

For the past years i've been working with JQuery alot, because it allow do things really fast and has full support in most browsers.

Although it is a lightweight library, it may be too much for what we want to achieve.

Couple days ago i published a way of doing FadeIn/Out in pure javascript, this time, im going to show how to make SlideDown/Up.

Let's get started.


    /* SLIDE UP */
    let slideUp = (target, duration=500) => {

        target.style.transitionProperty = 'height, margin, padding';
        target.style.transitionDuration = duration + 'ms';
        target.style.boxSizing = 'border-box';
        target.style.height = target.offsetHeight + 'px';
        target.offsetHeight;
        target.style.overflow = 'hidden';
        target.style.height = 0;
        target.style.paddingTop = 0;
        target.style.paddingBottom = 0;
        target.style.marginTop = 0;
        target.style.marginBottom = 0;
        window.setTimeout( () => {
              target.style.display = 'none';
              target.style.removeProperty('height');
              target.style.removeProperty('padding-top');
              target.style.removeProperty('padding-bottom');
              target.style.removeProperty('margin-top');
              target.style.removeProperty('margin-bottom');
              target.style.removeProperty('overflow');
              target.style.removeProperty('transition-duration');
              target.style.removeProperty('transition-property');
              //alert("!");
        }, duration);
    }

    /* SLIDE DOWN */
    let slideDown = (target, duration=500) => {

        target.style.removeProperty('display');
        let display = window.getComputedStyle(target).display;
        if (display === 'none') display = 'block';
        target.style.display = display;
        let height = target.offsetHeight;
        target.style.overflow = 'hidden';
        target.style.height = 0;
        target.style.paddingTop = 0;
        target.style.paddingBottom = 0;
        target.style.marginTop = 0;
        target.style.marginBottom = 0;
        target.offsetHeight;
        target.style.boxSizing = 'border-box';
        target.style.transitionProperty = "height, margin, padding";
        target.style.transitionDuration = duration + 'ms';
        target.style.height = height + 'px';
        target.style.removeProperty('padding-top');
        target.style.removeProperty('padding-bottom');
        target.style.removeProperty('margin-top');
        target.style.removeProperty('margin-bottom');
        window.setTimeout( () => {
          target.style.removeProperty('height');
          target.style.removeProperty('overflow');
          target.style.removeProperty('transition-duration');
          target.style.removeProperty('transition-property');
        }, duration);
    }

    /* TOOGLE */
    var slideToggle = (target, duration = 500) => {
        if (window.getComputedStyle(target).display === 'none') {
          return slideDown(target, duration);
        } else {
          return slideUp(target, duration);
        }
    }
Enter fullscreen mode Exit fullscreen mode

That's it, now you can use it like this:


// Specify Element and Duration (milliseconds)
slideUp(document.getElementById("target"), 1000);

slideDown(document.getElementById("target"), 1000);

slideToggle(document.getElementById("target"), 1000);

Enter fullscreen mode Exit fullscreen mode

I found this code online a few days ago and it works well, I hope it helps someone.

Take a look at my most recent project: VanillaJS Fully Customizable SelectBoxes

Thank you.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (12)

Collapse
 
kartofelek007 profile image
kartofelek007

with and without box-sizing:

let slideUp = (target, duration=500) => {
    target.style.transitionProperty = 'height, margin, padding';
    target.style.transitionDuration = duration + 'ms';
    const computed = getComputedStyle(target);
    if (computed.boxSizing === "border-box") {
        target.style.height = target.offsetHeight + 'px';
    } else {
        const pt = parseFloat(computed.paddingTop);
        const pb = parseFloat(computed.paddingBottom);
        const bt = parseFloat(computed.borderTopWidth);
        const bb = parseFloat(computed.borderBottomWidth);
        target.style.height = target.offsetHeight - pt - pb - bt - bb + 'px';
    }
....
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kabirpathak profile image
Kabir Pathak

Hi Bruno. Can you please explain what the purpose of this line of code is?
target.offsetHeight;
When i remove this from my code, the animation does not work. But this line keeps throwing a linting warning.

Collapse
 
jchibbard profile image
James Hibbard

This line forces the browser to restart a CSS animation.
Explanation here: css-tricks.com/restart-css-animation/
Further discussion here: sitepoint.com/community/t/why-does...

Collapse
 
sysmaya profile image
sysmaya

I like it. But I prefer to add it as prototype, so I call the function "natively"

Element.prototype.slideUp= function ( duration) {
// Slide code
};

element.slideUp(500);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
spamator12 profile image
spamator12

Does not work when you want slide multiple elements at once via querySelectionAll or for example
var list = document.getElementsByClassName("class1", "class2", "class3");

slideUp(list, 500); // error target.style relate to multiple elements...

Collapse
 
mooksz profile image
mooksz

This throws an error for me: error Expected an assignment or function call and instead saw an expression.

Its related to the lines:
target.offsetHeight;
target.offsetHeight;

Collapse
 
mooksz profile image
mooksz

Ah just relized its a bad copy from: w3bits.com/javascript-slidetoggle/

Collapse
 
jchibbard profile image

Might be because you are running in strict mode?
Try changing to void target.offsetHeight; see if that helps.
Ref.: css-tricks.com/restart-css-animation/

Collapse
 
pyrobri profile image
Brian

adding void just creates another linting issue asking to:
Remove this use of the "void" operator. (javascript:S3735)

Collapse
 
notrealdev profile image
notrealdev

Thank Bruno :D

Collapse
 
vasylkyrtyanyk profile image
Vasyl Kurtyanik

Hi, when I use these methods I also need to use the "stop" method from Jquery.
Because we need to stop our animation. Could you help me with it?

Collapse
 
bmsvieira profile image
Bruno Vieira

Hello,

Sure, i have to do some research but probably you can use:

var element =  document.getElementById(selector);
element.webkitAnimationPlayState = 'paused';
Enter fullscreen mode Exit fullscreen mode

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay