The Wayback Machine - https://web.archive.org/web/20150927103130/http://staff.washington.edu/fmf/2009/07/15/css-and-jquery-animation/
  • CSS, Javascript, jQuery, Web Apps 15.07.2009

    Animation in web applications can do more than add pizazz to a page, it can give good visual cues to the user as to what is happening.
    For example, consider an image carousel, where you have one largish image and smaller ones in the background.
    Having images animate to get larger and move into place (in addition to sliding on and off the screen) lets the user confirm the intended image is being shown.


    One place you often see transitions is on iPhone web applications.
    If your page is geared directly towards Mobile Safari, such as an iPhone web application, you can use CSS animations, which don’t work on other browsers.

    jQuery effects

    There are various ways to enable animations, and it’s common to see it done with a Javascript framework such as jQuery.
    This example uses jQuery effects to animate both the position and color of the square:

    The HTML is very straightforward:

    <div class="example">
      <div id="exjq" class="sprite"></div>
    </div>
    <input class="doanim" type="submit" name="exjq"
        value="Animate" />

    As you can see, the button and sprite are tied together by the name/id exjq.
    The relevant CSS is also straightforward:

    div.example {
      height: 45px;
      border: 1px black solid;
      position: relative;
    }
    div.example div.sprite {
      position: absolute;
      top: 10px;
      left: 10px;
      width: 25px;
      height: 25px;
      background: cyan;
    }

    All the CSS does is set up the initial state which is used for all the examples.
    The Javascript sets the button to trigger the effect, as well as defining the effect itself:

    // name of button == id of sprite
    function toggleClicked () {
      jQuery ('#'+this.name).toggleClass ('clicked');
    }
    
    function jqAnimate () {
      var target = jQuery ('#'+this.name);
      var anim = {
        left: '10px',
        backgroundColor: 'cyan'
      };
      // find preferred target state
      if (target.hasClass ('clicked'))
        anim = {
          left: '480px',
          backgroundColor: 'green'
        };
      // cancel current animation first
      target.stop ().doanim (anim, 1000, 'swing');
    }
    
    jQuery (function () {
      // used for all examples
      jQuery ('input.doanim').click (toggleClicked);
    
      jQuery ('input[name=exjq]').click (jqAnimate);
    });

    The code has been formatted to minimize truncating when viewing on an iPhone.
    Some notes:

    • Since WordPress also loads Prototype (after jQuery), the example uses jQuery instead of the more familiar $, since the latter would call Prototype, not jQuery.
    • If you’re using iPhone OS 3.0, the rounded button will change to a square button once you click it.
      In fact, all the buttons on the page will change once you click one of them.
      The buttons stay round with iPhone OS 2.2.1 and earlier.
    • iPhone OS 3.0 is notably smoother than earlier versions, due to the faster Javascript engine.
    • Be sure you load the jQuery color extension if you want to animate color (background-color in this example).
    • If the code didn’t cancel the current animation before queueing the next one, they would all stack up and essentially run forever.
      Also, the behavior of interrupting the running animation mimics CSS transitions, shown below.

    Animating using CSS3 transitions

    Webkit-based browsers (Safari, Chrome, etc.) support CSS3 transitions, which allow you to define animations using only CSS.
    You’ll still need Javascript to trigger the animation either by explicitly setting the final appearance or by changing an object’s class.
    If you do it by changing a class, then you have a greater separation of content, presentation, and scripting.

    This example uses -webkit-transition (as well as -moz-transition, for when Firefox gains transition support) to set up the animation:

    The same HTML is used as the previous example, except the label extrans is used instead of exjq.
    In addition, the only Javascript used from the previous example is the function which toggles the clicked class.

    The CSS is where the actual changes are declared:

    div#extrans {
      -webkit-transition: 1s ease-in-out;
      -moz-transition: 1s ease-in-out;
    }
    div#extrans.clicked {
      background: green;
      left: 480px;
    }

    Some notes on this example:

    • The -moz-transition attribute is defined even though it is not yet supported as of Firefox 3.5.
      In theory it could be added in a later version, and this example should being to work at that time.
      In the meantime, you’ll see the box chagne location and color, but it will jump between the two states.
    • Since both the start and end state are defined in CSS, it’s pretty trivial to change them.
      The jQuery example requires that you not only change the end state in Javascript, but the start state needs to be changed both in CSS and Javascript so they match.
    • This example is smoother than the jQuery example when using iPhone OS 2.2.1 and earlier.
      This is because even though Javascript is used to start things off, the animation itself is done by the browser’s rendering engine, rather than having a timer repeatedly call a function to change the CSS.
    • The default transition timing function is ease, but I chose to use ease-in-out, which seems very close to the jQuery timing function swing used in that example.
    • Using CSS transitions at this time limits you to Webkit-based browsers, but if you are deploying an iPhone web application, it’s a great method to use.
      It will be much smoother than using jQuery for animation on iPhone OS versions before 3.0.
      The difference won’t be as great using 3.0, especially on an iPhone 3Gs.

    Using transforms

    Another method of changing the location of an object is to use CSS transforms.
    This example uses -webkit-transform (and -moz-transform, which is supported in Firefox 3.5 and up) for the end state rather than changing left:

    As with the previous example, the HTML is the same except the label is changed to extform.
    The Javascript is unchanged.

    The CSS for this example is:

    div#extform div.sprite {
      -webkit-transition: 1s ease-in-out;
      -moz-transition: 1s ease-in-out;
      -webkit-transform: translateX(0px);
      -moz-transform: translateX(0px);
    }
    div#extform.clicked div.sprite {
      background: green;
      -webkit-transform: translateX(470px);
      -moz-transform: translateX(470px);
    }

    Notes for this example:

    • Webkit-based browsers will show the animation.
      As with the previous example, Firefox 3.5 will show the box moved and with the different color, but will not animate between the two states.
      Earlier versions of Firefox and other browsers will show the different color but the box will not move.
    • Safari on the desktop does not require the initial translateX(0px) transform, but it seems Mobile Safari for iPhone OS 3.0 does.
      If you do not set the initial state, the animation will not run to move the box to the right, but it will animate to show the box going to the left.
    • It’s very subjective, but using transforms seems a bit smoother rather than changing the left property.

    Interrupting animations

    As mentioned above, the jQuery example cancels any effects which are animating the box before starting a new one.
    Many times this is the desired behavior, since it both gives immediate feedback and it prevents the effects from becoming deeply queued up.
    CSS transitions always have this behavior.

    No matter what the initial state of an object, the transition will always take the amount of time defined either in the jQuery call or in the CSS transition attribute.
    In these examples the animations run for one second, and if you interrupt a running animation early on, you’ll see it will still take the full second to do the reverse animation.

    Posted by fmf @ 4:17pm

  • 2 Responses

      • I’m not sure in what way you wish to edit the animate button, but you can change the value in the HTML. You can also change the value with Javascript (frameworks such as jQuery make this pretty easy to do).

        However, if you want to make the button such that a user can click in it and edit the text, that would be more difficult. As far as I know, buttons can’t be ContentEditable, but you can put a text field over the button while editing the text, then set the button’s value when editing is done.

        Note that you’ll need to come up with a way to have the user say to edit the button’s text, since normally that would be done with a click, but a user would normally expect clicking the button to cause an action, not start editing text.

    Leave a Reply