Skip to content Skip to sidebar Skip to footer

Css Transition Opacity Is Not Working Where Element Had Display:none Then Changed To Display:block

Like the title said. I have this code: https://jsfiddle.net/fwo9ym1o/ //javascript var container = document.querySelector('#container'); container.style.display = 'block';

Solution 1:

It's because of the way styles are figured out. Style changes are expensive so they are effectively saved up until they are needed (a recalc check like .offsetHeight is called or the next frame needs to be drawn).

The following code should work. It includes an explanation of what (I think) is going on:

container.style.display = "block";
// container is actually still invisible// current style hasn't been calculated

container.offsetHeight;
// this forces a style recalc// so the current style for the container is figured out.// without this recalc, this element effectively has no style,// and so when you transition from its current style (null) to a different one (opacity: 1), it just snaps to the new value.

container.style.opacity = 1;
// this triggers the transition.// because the style was recalced before the transition was triggered,// it will transition _from_ those values.

jsFiddle

Solution 2:

May I suggest you use animation instead, it is much more appropriate than force a redraw.

var container = document.querySelector("#container");
container.classList.add('animateme');
.container {
  display: none;
  height: 150px;
  width: 150px;
  background-color: red;
}

.animateme {
  display: block;
  animation: animate 2s linear;
}

@keyframes animate {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
<divid="container"class="container"></div>

Solution 3:

Despite the marked 'right' answer I vote for the answer from LGSon above due to it being not a workaround but using natural CSS capability.

Plus it gives a cleaner code in JS due to the ease of toggling a class (container.classList.toggle('animateme')) and separation of concerns (JS does not manipulate CSS properties directly).

However I experienced the animation animate getting reset at the end to its zero keyframe i.e. to opacity: 0;

To make it stay I added animation-fill-mode: forwards; to .animateme selector like this (taken from this stackoverflow answer)

.animateme {
  display: block;
  animation: animate 2s linear;
  animation-fill-mode: forwards;
}

Solution 4:

Try this:

var container = document.querySelector("#container");
container.style.opacity = 1;

<div id="container" class="container"></div>

.container {
height: 200px;width: 200px;background-color: salmon;display: block;border-radius: 5px;opacity: 0;transition: opacity 2s ease-in-out;
}

JSFiddle

Post a Comment for "Css Transition Opacity Is Not Working Where Element Had Display:none Then Changed To Display:block"