Slide up/down effect with ng-show and ng-animate

I'm trying to use ng-animate to get a behavior similar to JQuery's slideUp() and slideDown(). Only I'd rather use ng-show

I'm looking at the ng-animate tutorial here - http://www.yearofmoo.com/2013/04/animation-in-angularjs.html,

and I can reproduce the fade in/out effect in the example provided.

How could I change the css to get slide up/down behaviour? Also, if possible, it's better that the css doesn't know about the component height in pixels. That way I can reuse the css for different elements.


Solution 1:

I've written an Angular directive that does slideToggle() without jQuery.

https://github.com/EricWVGG/AngularSlideables

Solution 2:

This is actually pretty easy to do. All you have to do is change the css.

Here's a fiddle with a very simple fade animation: http://jsfiddle.net/elthrasher/sNpjH/

To make it into a sliding animation, I first had to put my element in a box (that's the slide-container), then I added another element to replace the one that was leaving, just because I thought it would look nice. Take it out and the example will still work.

I changed the animation css from 'fade' to 'slide' but please note that these are the names I gave it. I could have written slide animation css named 'fade' or anything else for that matter.

The important part is what's in the css. Here's the original 'fade' css:

.fade-hide, .fade-show {
    -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
    -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
    -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
    transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
.fade-hide {
    opacity:1;
}
.fade-hide.fade-hide-active {
    opacity:0;
}
.fade-show {
    opacity:0;
}
.fade-show.fade-show-active {
    opacity:1;
}

This code changes the opacity of the element from 0 (completely transparent) to 1 (completely opaque) and back again. The solution is to leave opacity alone and instead change the top (or left, if you want to move left-right).

.slide-hide, .slide-show {
    -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
    -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
    -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
    transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
}
.slide-hide {
    position: relative;
    top: 0;
}
.slide-hide.slide-hide-active {
    position: absolute;
    top: -100px;
}
.slide-show {
    position: absolute;
    top: 100px;
}
.slide-show.slide-show-active {
    position: relative;
    top: 0px;
}

I'm also changing from relative to absolute positioning so only one of the elements takes up space in the container at a time.

Here's the finished product: http://jsfiddle.net/elthrasher/Uz2Dk/. Hope this helps!

Solution 3:

update for Angular 1.2+ (v1.2.6 at the time of this post):

.stuff-to-show {
  position: relative;
  height: 100px;
  -webkit-transition: top linear 1.5s;
  transition: top linear 1.5s;
  top: 0;
}
.stuff-to-show.ng-hide {
  top: -100px;
}
.stuff-to-show.ng-hide-add,
.stuff-to-show.ng-hide-remove {
  display: block!important;
}

(plunker)