CSS Transitions Do Not Work When Assigned Trough JavaScript

CSS transitions do not work when assigned trough JavaScript

To make transition work, three things have to happen.

  1. the element has to have the property explicitly defined, in this case: opacity: 0;
  2. the element must have the transition defined: transition: opacity 2s;
  3. the new property must be set: opacity: 1

If you are assigning 1 and 2 dynamically, like you are in your example, there needs to be a delay before 3 so the browser can process the request. The reason it works when you are debugging it is that you are creating this delay by stepping through it, giving the browser time to process. Give a delay to assigning .target-fadein:

window.setTimeout(function() {
slides[targetIndex].className += " target-fadein";
}, 100);

Or put .target-fadein-begin into your HTML directly so it's parsed on load and will be ready for the transition.

Adding transition to an element is not what triggers the animation, changing the property does.

// Works
document.getElementById('fade1').className += ' fade-in'

// Doesn't work
document.getElementById('fade2').className = 'fadeable'
document.getElementById('fade2').className += ' fade-in'

// Works
document.getElementById('fade3').className = 'fadeable'

window.setTimeout(function() {
document.getElementById('fade3').className += ' fade-in'
}, 50)
.fadeable {
opacity: 0;
}

.fade-in {
opacity: 1;
transition: opacity 2s;
}
<div id="fade1" class="fadeable">fade 1 - works</div>
<div id="fade2">fade 2 - doesn't work</div>
<div id="fade3">fade 3 - works</div>

Disabling and enabling css transition to initialize position

Adding a timeout to the addClass :

function onThumbnailClick(event) {
var index = parseInt(event.target.id.split('-')[1]);

initPortraitPanel(index);
$('.portraitDiv').setTimeout(addClass('active-transition'), 50);
}

codepen

Seems that this was already answered , downvoted, and deleted ... I don't know why

css3 transitions not firing first time in Firefox 4

Set left: 0 in your styles for ul; that got it working in the fiddle for me: http://jsfiddle.net/ctY68/4/

Looks like Gecko isn't considering your first style change a transition because there was no initial value set.

CSS transition doesn't start/callback isn't called

For a comprehensive explanation of why this happens, see this Q/A, and this one.

Basically, at the time you set the new style the browser still has not applied the one set inline, your element's computed style still has its display value set to ""
, because it's what elements that are not in the DOM default to.
Its left and top computed values are still 0px, even though you did set it in the markup.

This means that when the transition property will get applied before next frame paint, left and top will already be the ones you did set, and thus the transition will have nothing to do: it will not fire.

To circumvent it, you can force the browser to perform this recalc. Indeed a few DOM methods need the styles to be up to date, and thus browsers will be forced to trigger what is also called a reflow.

Element.offsetHeight getter is one of these method:

let tablehtml = `

<div id="spanky"

style="position: absolute;

left: 10px;

top: 10px;

background-color:blue;

width:20px;

height:20px;

transition: left 1000ms linear 0s, top 1000ms linear 0s;">

</div>`;

document.body.innerHTML += tablehtml;

let animdiv = document.getElementById('spanky');

animdiv.addEventListener("transitionend", function(event) {

animdiv.style.backgroundColor='red';

}, false);

// force a reflow

animdiv.offsetTop;

// now animdiv will have all the inline styles set

// it will even have a proper display

animdiv.style.backgroundColor='green';

Object.assign(animdiv.style, {

left: "100px",

top: "100px"

});

Clean way to programmatically use CSS transitions from JS?

There isn't a clean way at this moment (without using CSS Animations -- see the nearby answer by James Dinsdale for an example using CSS Animations). There is a spec bug 14617, which unfortunately wasn't acted upon since it was filed in 2011.

setTimeout does not work reliably in Firefox (this is by design).

I'm not sure about requestAnimationFrame -- an edit to the original question says it doesn't work reliably either, but I did not investigate. (Update: it looks like requestAnimationFrame is considered at least by one Firefox core developer to be the place where you can make more changes, not necessarily see the effect of the previous changes.)

Forcing reflow (e.g. by accessing offsetHeight) is a possible solution, but for transitions to work it should be enough to force restyle (i.e. getComputedStyle): https://timtaubert.de/blog/2012/09/css-transitions-for-dynamically-created-dom-elements/

window.getComputedStyle(elem).opacity;

Note that just running getComputedStyle(elem) is not enough, since it's computed lazily. I believe it doesn't matter which property you ask from the getComputedStyle, the restyle will still happen. Note that asking for geometry-related properties might cause a more expensive reflow.

More information on reflow/restyle/repaint: http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/

Change of opacity using css transition and vanilla JavaScript works only when fading out

This should work , Code pen link: http://codepen.io/saa93/pen/gLbvmQ

You would need to add this instead of directly setting opacity to 1

// Show button by increasing opacity
buttonElement.style.opacity = 0;
setTimeout(() => {
buttonElement.style.opacity = 1;
}, this.animationDelay + 20);


Related Topics



Leave a reply



Submit