CodeinWP CodeinWP

Triggering CSS3 Transitions With JavaScript

At the beginning of this month I wrote a post accompanied by five demo pages that showed that CSS3 transitions could be triggered with a number of different events/states in CSS.

That alone should help you see how these types of simple animations work. But let’s take this a bit further.

CSS pseudo-classes and media queries (which I used in that other post to trigger the transitions) represent certain states for certain elements. These states occur after specific events on the page. So naturally, CSS3 transitions can also be fired using any JavaScript event. Let’s try a simple click event that toggles a class name.

Here’s the HTML:

<div class="box"></div>

<input type="button" value="Let's Do This Thing" id="bt">

So we have a box with a class of “box”, and a button. Let’s add the following jQuery:

$(function() {
  $("#bt").click(function() {
    $(".box").toggleClass("box-change");
  });
});

This uses jQuery’s .toggleClass method to add or remove the specified class name. So let’s add the CSS:

.box {
  width: 300px;
  height: 300px;
  -webkit-transition: width 2s ease, height 2s ease;
  -moz-transition: width 2s ease, height 2s ease;
  -o-transition: width 2s ease, height 2s ease;
  transition: width 2s ease, height 2s ease;
}

.box-change {
  width: 400px;
  height: 400px;
}

The transitions are declared on the .box element (using all the necessary vendor prefixes), and they include the use of multiple transitions separated by a comma (in this case transitioning both width and height).

So when the button is clicked, after the .box-change class is added, this will trigger the transition.

It’s very similar to what you’d normally do with :hover, or :checked, or media queries, or whatever. But in this case the solution involves JavaScript. Here’s a demo page that shows this simple technique:

Why Would You Do This?

Well, there could be a number of reasons. Maybe you’re using JavaScript in your web page or web app to trigger something, so instead of using jQuery to animate CSS properties, you can leave the simple animations in your CSS, and avoid having those cluttering your scripting. Of course, some people feel animation belongs in JavaScript, not CSS. But for simple animations, I’m starting to agree with what seems to be the majority view — that CSS is the right place for these.

You could also use Modernizr and do something like this:

$(function() {

  $("#bt").click(function() {
    if (Modernizr.csstransitions) {
      $(".box").toggleClass("box-change");
    } else {
      // do some jQuery-based animations/transitions here
      // for IE 6-9
    }
  });
});

So with this code, you’re using Modernizr to detect whether the browser supports transtions, then only trigger them if they are present.

For Simple Animations

If you’re using more complex animations, then you might have to use keyframe-based animations combined with scripting. But for simple fades and slides, you might be able to use JavaScript combined with CSS3 transitions and fork some jQuery for browsers that don’t support them.

46 Responses

  1. This is great, I will try it today.

  2. Ishaan k says:

    Thanks, It is working.

  3. Chris Coyier says:

    I’m just gonna say: this is how I think it should be done. If the transition/animation is triggered by an event (like “click” in this article) that part should be handled by JavaScript and the transition/animation should be handled by CSS. Not everything works out that cleanly all the time, but I think that’s the proper separation of concerns.

    • Chris L says:

      Can you explain why? IE still doesn’t support CSS3 transistions, and FF just supported them. Why not use a JS library that can add support cross-browser. One type of function, for one type of language, cross-browser. Am I mistaken?

      • Chris isn’t referring to cross-browser support. He’s saying, if you are going to use CSS3 transitions, this is the proper way to separate behaviour from presentation.

        IE10 supports transitions, and FF has supported them since version 4. So yes, if you want cross browser support, then you’ll have to hack around the older versions.

        But you can also use Modernizr to detect support and then use straight JavaScript to do the same thing. Notice in the article, the last heading has a code example of how you would do this.

  4. Michael Dorf says:

    Just found your site on Dzone and enjoying the content very much, including this handy CSS3 tutorial! Thanks!

  5. Viktor says:

    That’s exactly what i was looking for! Thank you!

  6. meo says:

    or you could use a plugin that decides for you if the browser can handle CSS3 animations or not.
    I have made an example here: http://jsfiddle.net/meo/WsR5s/ i think its more efficient then writing twice the same animation.

  7. Deepak says:

    That’s exactly what i was looking for! Thank you!

  8. HKstrongside says:

    Sweet man, thanks for the tutorial.

  9. micky2be says:

    Why are you using jQuery? Iit’s not like you need it.
    All this ‘almost’ good exemples and tutorial make me think I should start my own technical blog.

    • It doesn’t matter whether or not it’s “needed” in these particular examples. I could have easily just used pure JavaScript to add/remove the class names. But the fact is, most people building websites nowadays are going to be using a JS library for something. Thus, if they get to a point where they need something simple like this, it will be much less code to use jQuery (or whatever library they’re using; I think my audience prefers jQuery).

      In my opinion, raw JavaScript is not really much of an option any more unless you don’t know the syntax for the library and just find it easier to use raw JS.

    • elo says:

      Same opinion.

      Why using jquery when it’s simple and standard to use pure javascript ? And no, everybody are not using it !

      This library is too much used nowadays, instead of thinking in real JS.

  10. ben kilbee says:

    Hi Louis,

    Nice simple tut, thanks for sharing.

    I’m just getting into animating things using CSS (rather than jquery like I usually do). I’m trying to rebuild a simple animation (divs changing size/position etc) that I have working in jquery, into CSS. First immediate problem is that my jquery version used the height of the window (window.innerHeight) to calculate positions. How could I get round this with CSS? Is that possible?

    Thanks again,
    Ben

  11. Cupidvogel says:

    The code snippets used in this page have a way of stylized display which is seen in many sites, including Mozilla Developer’s Network and Dreamincode. Is there an open-source css template available for this style?

    • It’s this plugin:

      http://alexgorbatchev.com/SyntaxHighlighter/

      Mine is an older version, but it’s basically the same one.

      • Cupidvogel says:

        Umm, the page you referred to has pretty similar code snippets, but the alternate lines aren’t banded as they are here. Any remedy?

      • Cupidvogel says:

        Ok ok, I got it, I downloaded the newer version, that’s why the alternate banding wasn’t there. Strange, that is an excellent feature, dunno why the creator disabled it in the later version. But how should I use in my HTML page to generate the style, like enclosing the code section within [code] tags or what?

        • You have to follow his documentation on how to do it. For mine, I have to do this:

          
          <pre name="code" class="js">
          // code here
          </pre>
          

          And then the script does the rest. I’ve also made a few aesthetic changes to the tool, and I’m hiding some of the options that I don’t want.

          • Cupidvogel says:

            Thanks a lot. And I noticed t now, the style of nesting comments on this page is cool. But don’t you think that if the level of replying propagates to 4 or 5 layers deep, the last answer will have a very small width to display its contents, to the point that it might be visually ugly?

          • The nesting stops I think at about 3 or 4, so it will basically look how it does now. It still looks bad on mobile though. I’ll have to do something about that, but not sure what.

  12. Cupidvogel says:

    Hmmm, your previous posts had a reply option at the bottom, your last post didn’t. May be the nesting indeed stops after 3 or 4 levels (it will be seen once this message is posted!), but then, the consistency is broken. Have you designed the site yourself, or are you using some other tool?

    • Yep, that’s how it works. That’s built into WordPress, and I have the option to choose how many levels deep.

      You can still reply to my last message above by hitting the nearest reply button in that section. It’s not too bad. Some people choose a shorter nesting, which I probably should do too, but this way it’s more definite what is being replied to what.

  13. Cupidvogel says:

    And the nice rounded corners on all the posts (presumably using border-radius, with proprietary prefixes) work fine in Firefox, but won’t work in IE. You can use the resource at http://www.curvycorners.net to have the same effect.

  14. Ciantic says:

    This is not novel observation but here goes:

    Most important for me about CSS transitions is possibility for hardware acceleration and frame-skipping. This means lower-powered devices can saw off the frames, and or jump to the very end of the animation instantly.

    Now there is animation timer in JavaScript, but still the browser/device can in theory be optimized to work faster for specific CSS transitions. And older crappy browsers simply don’t support transitions which is perfectly fine, they couldn’t deal with opacity changes anyway.

    I wish there were better API to trigger CSS transitions using JavaScript though.

  15. Andrey says:

    Hi everyone.I find your tutorials very very useful.Well,i tried to create the effect from apple site from the searchfield but i stuck when i need to switch the transition effect from right to left in exchange for the normal effect left-right.What should i do?I guess it’s about some kind of script right?I’ve already use it onfocus in order to resize the li-size from menu.I need some help with this.Thanks in advance!

    • Andrey, you’re going to have to provide a better explanation of what you’re referring to. I don’t know what you’re trying to transition, and which part you’re having trouble with. The “li’? The search field? And if you can provide a link to a demo, that would be good.

      You can create one at jsfiddle.net, jsbin.com, codepen.io, etc.

  16. Majeed says:

    I saw something AwardWinningFjords.com which was using jQuery to trigger CSS3 Animations in another way using: element.css({ //new stlye })

    $(".elem1").click(function(){ 
    $(".elem2").css({ left: '-1000px' })
    });
    

    Hope you find it useful :p

  17. Don says:

    You solved one of my biggest problems!!! Thanks buddy. \/

  18. JacksonFiveIsAlive says:

    The title of this article really should be: Triggering CSS3 Transitions With jQuery

  19. Laura says:

    How would you get it to scale from a central point rather than the top corner?

    Cheers

  20. This works great! I have been playing around with using just CSS, pure JavaScript and jQuery but of all the tests and examples tried nothing works a elegantly as your code Louis. Thank you so much for sharing this, this really has made my day.

  21. Alex says:

    Not working in Chrome

    • Thanks, sorry about that. I switched over to HTTPS recently and that page’s scripts were being blocked by Chrome for security reasons. I’ve corrected it now, although other demo pages probably have other similar problems because I didn’t correct those ones yet.

  22. Izak van Langevelde says:

    Why do we need JQuery to get this to work?

    
    If I replace your 
        $(function() {
          $("#bt").click(function() {
            $(".box").toggleClass("box-change");
          });
        });
    
    by
    
         <script>
          function foo(){
             document.getElementById('bt').classList.toggle('box-change');
          }
         </script>
    
       <input type="button" value="Let's Do This Thing" id="bt" onclick="foo()">
    
    

    this leaves the logic of your method intact.
    However, the transition does not animate…

    • Izak van Langevelde says:

      Oops, I did it again: should have tested my code before submitting.
      This doesn’t need jQuery, it works as expected.

      Sorry for the hassle!

  23. Jonas says:

    Demo is not working

  24. Miltons says:

    Thank you very much, I found this very helpful.
    The content is well explained

    • Miltons says:

      But is it that we should only use this

      $(function() {

      $("#bt").click(function() {
      if (Modernizr.csstransitions) {
      $(".box").toggleClass("box-change");
      } else {
      // do some jQuery-based animations/transitions here
      // for IE 6-9
      }
      });
      });

      /code>

  25. Thank you very much.This is very helpful content but i tried many times couldnt get that results b/c my https recently for that page’s scripts were being blocked by Chrome :(

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).