Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

css transitions on new elements

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?

like image 289
Vito De Tullio Avatar asked Aug 23 '12 09:08

Vito De Tullio


People also ask

How do you make different transitions in CSS?

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.

How do I fade an element in CSS?

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.

What is the difference between transition and transform in CSS?

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.


2 Answers

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

like image 126
jfriend00 Avatar answered Oct 05 '22 22:10

jfriend00


I found a nicer way to trigger layout and make transitions work just after appending the element to the DOM:

window.getComputedStyle(element).opacity; 
like image 43
demian85 Avatar answered Oct 05 '22 22:10

demian85