Skip to main content

Fade animations on HTML elements

Sometimes, fading in an element (for example, using jQuery's fadeIn() method, or setting an element's transition and opacity CSS values) will not work, and the element just displays immediately.

 css.jpeg

The reason for this is due to two things: concurrency issues, and transitions on the display property.

Element display is not transitionable

An element can't have a fade animation if you're changing its display property (e.g. from none to flex). While this doesn't seem entirely related to the problem, it's part of it. Suppose you have some code that does this:

// Assume some-element currently has display:none and opacity:0.
$("#some-element").css({"display": "flex"});
$("#some-element").css({"opacity": "1", "transition": "opacity 0.5s ease"});

The expected result of this code is that the element fades in over half a second. Instead: it just appears instantly. The reason is that the command to change the element's display property to flex has not yet been rendered by the browser when the opacity property is changed - so the browser does not animate the transition at all.

Meanwhile, the following code works correctly, animating the fade in:

// Assume some-element currently has display:none and opacity:0.
$("#some-element").css({"display": "flex"});

// Wait 50ms to let the browser catch up with the display:flex change.
setTimeout(function () {
  $("#some-element").css({"opacity": "1", "transition": "opacity 0.5s ease"});
}, 50);

Warning: jQuery animations are not exactly in sync with CSS transitions

If you're mixing jQuery .animate() calls with normal CSS transitions, be aware that the two don't always do the same thing, even if you're using the same timeframes for the given animations. You may find that one animation finishes before the other or vice versa; you'll need to adjust the respective animation times and try and get them to match each other.

Another possible solution to this is to specify the "swing" animation method when using $.animate(), which more closely resembles the normal CSS ease transition method.