Doua Beri Doua Beri - 2 months ago 14
CSS Question

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";

//this is not working
//container.style.opacity = 1;


//this is working
setTimeout(function() {
container.style.opacity = 1;
}, 0);

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

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


So, I've changed the
container.style.display = "block";
then applied
container.style.opacity = 1;
and the transition is not happening.

It works if I run everything in a new thread.

NOTE: I can't use visibility. It has to be display:none

Answer

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

Comments