Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 transitions to dynamically created elements

Tags:

I'm trying to animate a dynamically created html element with CSS3 transitions.

I want the animation to start just before the element is created.
For these i create a class that set the original position of the element and then I set the target position by the jquery css() method

But the new element it just apears in the target position without any transition.

If I use a setTimeout of 0ms to set the new css value it work.

There is something I'm doing wrong? or is a limitation? I don't think I should need to use the setTimeout workaround.

Thanks!

UPDATE: Here is a link with the code running on jsfiddle.net for you to experiment. http://jsfiddle.net/blackjid/s9zSH/

UPDATE I've updated the example with the solution in the answer.
http://jsfiddle.net/s9zSH/52/

Here is a fully working example code

<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
        <script type="text/javascript">

        //Bind click event to the button to duplicate the element
        $(".duplicate").live("click", function (e){
            var $to = $("#original .square").clone()
            $("body").append($to);
            if($(e.target).hasClass("timeout"))
                //With setTimeout it work
                setTimeout(function() {
                    $to.css("left", 200 + "px");
                },0);
            else if($(e.target).hasClass("notimeout"))
                // These way it doesn't work
                $to.css("left", 200 + "px");
        });

        </script>
        <style type="text/css">
        .animate{
            -webkit-transition: all 1s ease-in;
        }
        .square{
            width:50px;
            height:50px;
            background:red;
            position:relative;
            left:5px;
        }
        </style>
    </head>
    <body>
        <div id="original">
            <div class="square animate"></div>
        </div>

        <button class="duplicate timeout">duplicate with setTimeout</button>
        <button class="duplicate notimeout">duplicate without setTimeout</button>
    </body>
</html>
like image 386
blackjid Avatar asked Oct 19 '10 15:10

blackjid


People also ask

How do you create transition effects using css3?

To make the transition occur, you must specify at least two things — the name of the CSS property to which you want to apply the transition effect using the transition-property CSS property, and the duration of the transition effect (greater than 0) using the transition-duration CSS property.

What are css3 transitions and transform?

So what are transforms and transitions? At their most basic level, transforms move or change the appearance of an element, while transitions make the element smoothly and gradually change from one state to another.

Why do you use css3 transitions?

CSS transitions provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time.

How do you trigger transition CSS?

Triggering transitions You can trigger CSS transitions directly with pseudo classes like :hover (activates when the mouse goes over an element), :focus (activates when a user tabs onto an element, or when a user clicks into an input element), or :active (activates when user clicks on the element).


1 Answers

You don't need to use a timeout. Timeout works because the page is reflowed between setting styles. Reflowing recalculates the styles.If you don't recalculate the styles, the second style simply overwrites the first. That's the real issue.

Rather, you can simply:

obj.className = style1;
window.getComputedStyle(obj).getPropertyValue("top");
obj.className = style2;

If you're animating multiple objects, you only need to "pump" the style calculator once:

obj.className = style1;
obj2.className = style1;
obj3.className = style1;
window.getComputedStyle(obj).getPropertyValue("top");

obj.className = style2;
obj2.className = style2;
obj3.className = style2;

Tested in chrome12 on mac

like image 164
mmaclaurin Avatar answered Dec 21 '22 22:12

mmaclaurin