PlainJS: fade-in & fade-out

8min read

We use fade-in and -out animations on elements to give our users a more pleasant experience when they view our website or app. We use them for elements that get lazyloaded, toggled or whenever we want to make the appearance/ disappearance of something look smooth.

Back in the days most developers probably used jQuery to do the job since it was part of most websites anyway and provided a very convenient way to do it (fadeIn/ fadeOut). With jQuery slowly fading out from web development I want to show in this article how to make a fadeIn and fadeOut function in plain javascript.

In order to make an element fade-in/fade-out we essentially need to change its opacity from 0 to 1 in a timeframe that is detectable for the human eye. Please note that changing the opacity of an element can also be done purely via CSS3 and if we just need to do that it is the most preferable because most performant solution. The way how to achieve this with CSS3 would be to either use the

transition property:

  • set the opacity of the element to either zero or 1 (depending on whether fade-in or fade-out is desired)
  • set transition: [property] [time] [easing] => for example transition: opacity .4s ease
  • apply via javascript a new class .fadein/.fadeout to the element with opacity set to zero (fade-out) or 1 (fade-in)

or via a

keyframe animation:

  • create a new keyframe animation @keyframe fadein (or @keyframe fadeout) that goes from opacity: 0 to opacity: 1 (or opacity: 1 to opacity: 0)
  • apply via javascript a new class .fadein/.fadeout that has all required animation properties => e.g. animation: fadein .4s linear

However, with both of these techniques an element that gets faded out still would occupy blank space. It would be invisible but not gone (similar to visibility: hidden). Sometimes we want the element to be gone and not take any space after it is faded out. We want it to be set to display: none. We can achieve this easily with Javascript.

Please note that I am using ES6 syntax. If you are not familiar with this please see my es6 article series and keep in mind that it needs to be transpiled to ES5 for older browsers via babel.io.

fadeIn

First we assign an anonymus function to our variable fadeIn that has an element (el) as it’s first parameter, an option to make a smooth fade-in animation which defaults to true as it’s second parameter and displayStyle ‘block’ as default for it’s third parameter. We start with setting the elements opacity to zero and apply display: block because we assume that it’s current value could be display: none. If smooth is not false we declare a variable with let opacity, starting from zero, and also declare another variable let request, without assigning any value yet.

Afterwards we create another anonymus function that is bound to the variable animation and sets the opacity of our element equal to the result of the value from our previously declared opacity variable plus 0.04. After the first iteration the value would be 0 + 0.04 = 0.04, in the second round 0.08 and so on until it reaches the condition being higher or equal to 1.

I chose 0.04 as it creates a fadeIn animation in approximately 400ms. Feel free to play with the numbers to make it optimal for your case. You can use console.time() (in the beginning of your function run) and console.timeEnd() (in the end of your function run) to understand the timings.

Once the condition is passed we make sure that opacity is exactly one and cancel our animation frame (see next step) via the cancelAnimationFrame(fn) method.

We use requestAnimationFrame for creating the iteration because this way we give the control to the browser when to re-render the layout and not force it on it as we would do with either setTimeout or setInterval. The “problem” with using a recursive setTimeout or setInterval for drawing our animations is that we command the browser at a predefined time to run our animation. Since the browser is single threaded this intervention could lead to a sluggish experience as other javascript (potentially with other animations) may need to be executed too. With requestAnimationFrame the browser controls the redrawing of the layout at an eye-friendly approximate 60hz framerate and provides us with a smooth animation that is not conflicting with any other javascript tasks which may run simultaneously. To be fair it is unlikely that our fade-in or fade-out animation would cause a sluggish experience for the user because it is very fast over but it is generally good practice to use requestAnimationFrame for animations and that’s why we will go with it.

We assign an anonymus function to our rAf variable that assigns a recursive call to itself via the requestAnimationFrame method. In other words we let the function call itself. Please be careful when you do recursive calls and always define a condition under which it gets cancelled. Otherwise you will create an infinite loop and crash your system/ browser.

We assign the function call to our variable request which we declared earlier. The reason we declared request outside of the rAf function is scope. We need to be able to access it via the cancelAnimationFrame method from within the animation function. We run animation and alter the opacity of our element on each iteration.

Finally we call our rAf function to get it all started. In case you wonder about the else condition which runs when smooth is set to false: Technically it does ruin the “fadein experience” because it would set the element’s opacity “instantly” to 1 but it makes the function more versatile and we can achieve that only with a few lines of code.

fadeOut

The fadeOut method is basically an inverted function of our previous explained fadeIn method. I will not go through it in such detail because it is essentially the same as the fadein method just altering the opacity from 1 back to zero and applying display: none in the end right before the iteration gets stopped to leave no blank space behind.

13 replies

Trackbacks & Pingbacks

  1. jebjeed888 says:

    … [Trackback]

    […] There you will find 37517 additional Information on that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  2. Homepage says:

    … [Trackback]

    […] Find More Informations here: ilearnjavascript.com/plainjs-fadein-fadeout/trackback/ […]

  3. … [Trackback]

    […] There you can find 84476 more Info to that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  4. … [Trackback]

    […] Read More on that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  5. … [Trackback]

    […] Find More on that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  6. … [Trackback]

    […] Find More to that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  7. … [Trackback]

    […] Read More on to that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  8. … [Trackback]

    […] Find More here on that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  9. … [Trackback]

    […] Here you will find 40759 additional Information on that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  10. lucabet says:

    … [Trackback]

    […] Read More Information here to that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  11. … [Trackback]

    […] Find More to that Topic: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

  12. Homepage says:

    … [Trackback]

    […] Read More here: ilearnjavascript.com/plainjs-fadein-fadeout/ […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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