Search code examples
jqueryjquery-animatejquery-effects

jquery expand from (and collapse into) a small square


I'd like to create a small 16px square icon that, when clicked, "expands" into a large 600px x 100px banner showing additional content that overlays part of the page. Then the user can click a close button on the banner and it will "collapse" back into the icon.

Essentially I'm looking for an ability to smoothly animate from this:

------------------------------------------------------------------
|                                                                |
|                                                       [icon]   |
|                                                                |
|                                                                |
|          Page content here                                     |
|          more page content here                                |
|          even more page content here                           |
|          yet more more page content here                       |
|          another line of page content                          |
|          and another.                                          |
|                                                                |
|                                                                |

To this:

------------------------------------------------------------------
|                                                                |
|   ----------------------------------------------------------   |
|   |                                                    [x] |   |
|   |                                                        |   |
|   |      Content inside banner                             |   |
|   |      goes here                                         |   |
|   |                                                        |   |
|   ----------------------------------------------------------   |
|          another line of page content                          |
|          and another.                                          |
|                                                                |
|                                                                |

And then animate back again when the user clicks the close button.

What's a good way to do this with jquery with good performance and browser compatiblity?

Most of my app's users are on downlevel browsers, so any solution should work on IE7+, iPad2+, and modern desktop and mobile browsers-- although if peformance is awful on old browsers I may just ditch the animation there.


Solution

  • For this specific case, I'd go with a absolutely positioned div, that expands from a 16 pixels square to a 600x100px rectangle.

    You could animate that using CSS3 transitions:

    .foobar {
      width: 16px;
      height: 16px;
      position: absolute;
      top: 0;
      right: 0;
      transition: all 0.4s ease-out;
    }
    
    .foobar.expanded {
      width: 600px;
      height: 100px;
    }
    

    So that when you click the square you have just to add the expanded class, and remove it to make the div collapse, like this (using jQuery to manage the event):

    $('.foobar').on('click', function (event) {
      event.preventDefault();
      $(this).toggleClass('expanded');
    });
    

    Or with jQuery's .animate():

    $('.foobar').on('click', function (event) {
      event.preventDefault();
      var $this = $(this);
      if ($this.width() === 600) {
        $this.animate({
          width : 16,
          heigth : 16
        }, 400);
      } else {
        $this.animate({
          width : 600,
          height : 100
        }, 400);
      }
    });
    

    Using this as the base CSS:

    .foobar {
      width: 16px;
      height: 16px;
      position: absolute;
      top: 0;
      right: 0;
    }
    

    As you can see, the implementation is very straightforward.

    As a general rule, CSS transitions are way better than animations made using javascript; the downside is that older browsers don't support them. Personally, I'd go with CSS transitions.