I cannot find a way to use css transitions on newly created dom elements.
let's say I have an empty html document.
<body> <p><a href="#" onclick="return f();">click</a></p> </body>
I also have this css
#id { -moz-transition-property: opacity; -moz-transition-duration: 5s; opacity: 0; } #id.class { opacity: 1; }
and this js
function f() { var a = document.createElement('a'); a.id = 'id'; a.text = ' fading in?'; document.getElementsByTagName('p')[0].appendChild(a); // at this point I expect the span element to be with opacity=0 a.className = 'class'; // now I expect the css transition to go and "fade in" the a return false; }
but, as you can see on http://jsfiddle.net/gwxkW/1/ when you click the element appears instantaneously.
If I try to set the class in a timeout()
i often find the result, but to me it seems more a race between javascript and the css engine. Is there some specific event to listen? I tried to use document.body.addEventListener('DOMNodeInserted', ...)
but it's not working.
How can I apply css transitions on newly created elements?
Transitioning two or more properties You can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.
In the CSS, use the @keyframes rule paired with fadeIn. At 0%, set the opacity to 0. At 100%, set the opacity to 1. This creates the fade-in effect.
So, what's the difference between CSS Transform and CSS Transition? The Transform property in CSS moves or modifies the appearance of an element, whereas the Transition property seamlessly and gently transitions the element from one state to another.
In Firefox, it does appear to be a race between layout completing and the CSS transition. Chrome is much more predictable. If I set the class name on a setTimeout()
, Chrome always works, Firefox only works if the setTimeout()
time is long.
With this code in Firefox (even using the setTimeout()
), the text shows immediately:
function f() { var a = document.createElement('a'); a.id = 'id'; a.innerHTML = ' fading in?'; document.getElementsByTagName('p')[0].appendChild(a); // at this point I expect the span element to be with opacity=0 setTimeout(function() { a.className = 'fadeIn'; }, 10); return false; }
But, if I force a reflow by requesting a property that can only be returned after layout, it then starts to work in Firefox:
function f() { var a = document.createElement('a'); a.id = 'id'; a.innerHTML = ' fading in?'; document.getElementsByTagName('p')[0].appendChild(a); // at this point I expect the span element to be with opacity=0 // request property that requires layout to force a layout var x = a.clientHeight; setTimeout(function() { a.className = 'fadeIn'; }, 10); return false; }
Furthermore, once I've request that property to force a layout, I can even remove the setTimeout()
and the animation works in Firefox.
function f() { var a = document.createElement('a'); a.id = 'id'; a.innerHTML = ' fading in?'; document.getElementsByTagName('p')[0].appendChild(a); // at this point I expect the span element to be with opacity=0 // request property that requires layout to force a layout var x = a.clientHeight; a.className = 'fadeIn'; return false; }
You can see this last one work here in both Chrome and Firefox: http://jsfiddle.net/jfriend00/phTdt/
And, here's an article that discusses the phenomenon: http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html
I found a nicer way to trigger layout and make transitions work just after appending the element to the DOM:
window.getComputedStyle(element).opacity;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With