thinking stiff

CSS transitions with Javascript

Posted in Programming by thinkingstiff on 2013/02/08

Assigning CSS transitions in Javascript can be tricky due to both order of assignment and timing. Stepping though while debugging can give you different results than running live, which makes it difficult to find the problem. In answering CSS transitions do not work when assigned trough JavaScript on Stackoverflow, I came up with the following guidelines.

To make transition work, three things have to happen.

1. the element has to have the property explicitly defined (ex: 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, there needs to be a delay before #3 so the browser can process the request. If you are debugging, it will often appear to work because you are creating this delay by stepping through it, giving the browser time to process. Adding transition to an element is not what triggers the animation, changing the property does.

To create this delay you can either add the first two steps to the HTML at design time, or create the delay in Javascript with .setTimeout().

Demo: http://jsfiddle.net/ThinkingStiff/QNnnQ/

HTML:

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

CSS:

    .fadeable {
        opacity: 0;
    }
    
    .fade-in {
        opacity: 1;
        transition:             opacity 2s;
            -moz-transition:    opacity 2s;
            -ms-transition:     opacity 2s;
            -o-transition:      opacity 2s;
            -webkit-transition: opacity 2s;
    }

Script:

    //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';
        
    }, 100);

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s