1

I was experimenting with CSS3 and I found a strange thing. When I set an CSS animation to the height property and use cubic bezier (0,n,0.5,1) where n is greater than 0.5, the element moves downwards during the animation.

Is this interpretation right? It seems to be the same in Firefox and Chrome. Live demo (for some reason doesn't work in chrome)

andyb
  • 43,435
  • 12
  • 121
  • 150
m93a
  • 8,866
  • 9
  • 40
  • 58

2 Answers2

2

I doesn't work in Chrome because you are using % in the keframes instead of px, while the parent element has no height set.

And the overall behavior is correct, this is because you've made the elements inline elements, which causes them to be aligned to the baseline by default, and while the behavior is most visible with animations of different speed, you would experience the same behavior towards the end of a synchronously linear movement, ie it's not really related to the cubic bezier easing.

You can fix this by for example changing the vertical-align to top

.box {
    width: 50px;
    display: inline-block;
    vertical-align: top;
    background: #5f0;
    height: 100px;
    border: 1px solid #000;
}

or by floating the elements instead of making them inline elements.

.box {
    width: 50px;
    float: left;
    background: #5f0;
    height: 100px;
    border: 1px solid #000;
}
ndm
  • 59,784
  • 9
  • 71
  • 110
  • For some reason SO did not show that this answer was already posted while I was adding mine, otherwise I might not have carried on. Answers are almost identical, so `+1` – andyb Oct 22 '13 at 13:55
  • Oh! I don't know what answer should I accept! :D Thank you **ndm** and **andyb** - I forgot about the baseline! – m93a Oct 22 '13 at 16:23
  • @m93a Well, ndm was first... :) – andyb Oct 23 '13 at 07:35
1

The demo does not seem to work in Chrome problem is because the height of the from keyframe is 100% but that means 100% of the containing element (in this case <body>) but there is no height set on the <body>. Two solutions to this, either set:

body {
    height:100px;
}

or

@-webkit-keyframes anim {
    from {
        height:100px;
    }
    to {
        height:0;
    }
}

The actual moving elements problem is because the elements are display:inline-block but there is no vertical-align set, so the browser is using the default vertical-align:baseline to align the elements to. Since the animation properties of the cubic-bezier for each block are different, the baseline is moving and therefore the elements are too.

See my answer on Why does this inline-block element have content that is not vertically aligned for more detail on why the baseline moves.

So your problem would not occur if the animation properties on each block was the same.

For my demo, I have used vertical-align:top; but there are other values depending on your needs. I also set the animation-fill-mode:forwards so that "after the animation ends (as determined by its animation-iteration-count), the animation will apply the property values for the time the animation ended" - from the CSS documentation.

CSS

@keyframes anim {
    from {
        height: 100px;
    }
    to {
        height: 0;
    }
}
@-webkit-keyframes anim {
    from {
        height:100px;
    }
    to {
        height:0;
    }
}
.box {
    width: 50px;
    display: inline-block;
    background: #5f0;
    height: 100px;
    border: 1px solid #000;
    vertical-align:top;
}
.box:first-of-type {
    animation: anim 10s cubic-bezier(0, 1, .5, 1);
    -webkit-animation: anim 10s cubic-bezier(0, 1, .5, 1) forwards;
}
.box:last-of-type {
    animation: anim 10s cubic-bezier(0, .5, .5, 1);
    -webkit-animation: anim 10s cubic-bezier(0, .5, .5, 1) forwards;
}

HTML

<div class=box></div>
<div class=box></div>
Community
  • 1
  • 1
andyb
  • 43,435
  • 12
  • 121
  • 150