9

I have a message box which I want to slide down on click. I do this by adding a css class through Angular (and jQuery in my example). But my CSS transition does not take effect.

Is there any obvious mistake I'm doing?

Here's my fiddle: http://jsfiddle.net/mBKXn/

and my code:

// jQuery
$('.test').on('click',function(){
  $('#msgContainer').toggleClass('msgShow');
});

// HTML
<div class="container">
    <div id="msgContainer" class="msg">
        <p>Message here</p>
        <p>T2</p>
        <p>T4</p>
    </div>
    Test text
</div>

<button class="test">Click</button>

// CSS
.container{
    position: relative;
    height: 200px;
    width: 400px;
    border: solid 1px #222;
}

.msg{
    position: absolute;
    top: 0;
    background-color: #FEEFB3;
    height: 0;
    width: 100%;
    overflow: hidden;
    -webkit-transition: height 0.8s linear;
    -moz-transition: height 0.8s linear;
    -o-transition: height 0.8s linear;
    -ms-transition: height 0.8s linear;
    transition: height 0.8s linear;    
}

.msgShow{
    height: auto;
}
Steven
  • 19,224
  • 47
  • 152
  • 257
  • possible duplicate of [jQuery duration for toggleClass issue](http://stackoverflow.com/questions/6817233/jquery-duration-for-toggleclass-issue) – isherwood Jan 15 '14 at 19:43
  • 2
    possible duplicate of [CSS transition height: 0; to height: auto;](http://stackoverflow.com/questions/3508605/css-transition-height-0-to-height-auto) – A. Wolff Jan 15 '14 at 19:48

3 Answers3

6

you need to set a defined height. Height:auto won't work as this is the default height value.

see the specs for the height property here: http://www.w3.org/TR/CSS2/visudet.html#the-height-property

http://jsfiddle.net/mBKXn/7/

.msgShow{
    height: 100%;
}
kasper Taeymans
  • 6,950
  • 5
  • 32
  • 51
6

To animate height from 0 to auto you have to use max-height instead:

.msg{
    position: absolute;
    top: 0;
    background-color: #FEEFB3;
    max-height: 0;
    width: 100%;
    overflow: hidden;
    -webkit-transition: max-height 0.8s linear;
    -moz-transition: max-height 0.8s linear;
    -o-transition: max-height 0.8s linear;
    -ms-transition: max-height 0.8s linear;
    transition: max-height 0.8s linear;    
}

.msgShow{
    max-height: 1000px;
}

Seems to work: http://jsfiddle.net/mBKXn/3/

Also take a look at this question.

Community
  • 1
  • 1
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • 4
    This does work, but it's problematic because once the max-height value exceeds the height, there are no further *visual* changes even though the browser continues "animating". When you click again, there's a noticeable pause while the value animates *down* to the actual height. – Pointy Jan 15 '14 at 19:50
  • 1
    `max-height: 100%;` should be enough ;) http://jsfiddle.net/mBKXn/6/ But Pointy makes a good point – A. Wolff Jan 15 '14 at 19:50
  • @A.Wolff yes but that's 100% of the *parent* element height, so you still get the pause when toggling back to 0. – Pointy Jan 15 '14 at 19:52
  • @Pointy ya, that's correct and can be an issue. Do you know how to solve it? – A. Wolff Jan 15 '14 at 19:53
  • Yes, it's true. So when using this method, one should set reasonable max-height (not 1000px like in my example) to reduce animation delay on back toggle. – dfsq Jan 15 '14 at 19:58
  • I set the max-height in `.msg` and height: 100% in `.msgShow` and it works great. Even with a very long list, it does not take extra time to slide up. See fiddle: http://jsfiddle.net/mBKXn/9/ – Steven Jan 15 '14 at 19:59
  • I can't think of anything better, but I'm really bad at CSS transform puzzles. – Pointy Jan 15 '14 at 20:00
  • @Steven but you set `max-height: 100px`. This is not the same as `auto`. – dfsq Jan 15 '14 at 20:03
  • @Pointy Doesn't work for me Chrome 31.0.1650.63, Linux. – dfsq Jan 15 '14 at 20:11
  • @Pointy you give me the idea of animating top instead (if element height < container height): http://jsfiddle.net/mBKXn/10/ PS: damn, still not really working :( – A. Wolff Jan 15 '14 at 20:12
  • @dfsq transform should be vendor prefixed but i'm unable to make it works either – A. Wolff Jan 15 '14 at 20:13
  • Yes it probably needs a vendor prefix. The reason "transform" is useful is that percentages in the "translateY()" function are relative to the *element* bounding box. Both "top" and "margin-top" have the problem of percentages being relative to something else. – Pointy Jan 15 '14 at 20:15
3

Another (older IE compliant) way to do this is through slideToggle.

Updated Fiddle that works and another Fiddle where I removed some of your transition css and it makes the animation smoother in my opinion.

your code needs a slight change:

$('.test').on('click',function(){
  $('#msgContainer').slideToggle('slow');
});

and your class needs a slight change:

.msg{
    display:none;
    position: absolute;
    top: 0;
    background-color: #FEEFB3;
    height: auto;
    width: 100%;
    overflow: hidden;
}
erikrunia
  • 2,371
  • 1
  • 15
  • 22
  • 2
    He's doing a css transition from height `200px` to height `auto` (`auto` is the cause) – Kevin B Jan 15 '14 at 19:49
  • Wrong. I'm using CSS transition which is the animation. As both Kevin and Kasper points out, css transition does not work with `auto` height. – Steven Jan 15 '14 at 19:52