jQuery width change (animation) causes vertical shift in Firefox/IE Any clues?

Go To StackoverFlow.com


Example here (check out the header): http://brendonoliverlamb.com/

using this code:

    $('.flipper').wrap('<span id="tmp"></span>');
    $('#tmp').css({ width: $('.flipper').outerWidth() + 'px' });
    $('.flipper').fadeOut(500, function () {
        $('#tmp').animate({ width: $(this).outerWidth() + 'px' }, 250);
        $(this).fadeIn(500, function () {

The problem I am having is the words around the word that is flipping are shifting during the animation...

I was guessing perhaps it has something to do with the fadeOut and maybe a height change but for the life of me I haven't found a solution...

I just want the "flipper" class element to change words smoothly- fade out, adjust the width so the text to the right fits, fade in.

Couldn't find a plugin for this either :/

2012-04-04 01:01
by godofleet
Please show us the relevant HTML - jfriend00 2012-04-04 01:07


I found a couple issues. In some browsers, there was word-wrap happening when you switched to a longer word and in all browsers, there was a vertical alignment problem. One can see the problem in a more isolated way here: http://jsfiddle.net/jfriend00/BSmwF/ and you can clearly see the jump happens only when a longer word replaces a shorter word causing the temporary word-wrap.

I also simplified the code significantly, with no need for the wrap and unwrap.

The problem goes away if you add this CSS which prevents the word wrap and fixes the alignment issue:

.flipper {
    white-space: nowrap;
    overflow: hidden;
    vertical-align: bottom;

Working demo here: http://jsfiddle.net/jfriend00/EgfYU/

And, I changed to simpler code without the wrap/unwrap and used fadeTo() so the span only has it's opacity changed and never gets set to display: none:

var flipWords = ["a professional", "an experienced", "an innovational", "an enthusiastic"];

//Do not edit below//
//set initial
var flipperCountCurrent = 0;
setTimeout(flipper, 1500);
function flipper() {

    if (flipperCountCurrent < flipWords.length - 1) {
        flipperCountCurrent += 1;
    } else {
        flipperCountCurrent = 0;

    //no animation
    // $(".flipper").html(flipWords[flipperCountCurrent]);

    var flipperSpan = $('.flipper');
    var origWidth = flipperSpan.width();
    flipperSpan.fadeTo(500, 0, function () {
        flipperSpan.html(flipWords[flipperCountCurrent]).css("width", "auto");
        var newWidth = flipperSpan.width();
            .animate({ width: newWidth + 'px' }, 250)
            .fadeTo(500, 1);

    setTimeout(flipper, 1500);


Note, I modified the timer time for faster cycling while debugging.

2012-04-04 01:28
by jfriend00
quality work sir, was banging my head on that one for a bit too long haha. Glad i opened up this account :) - godofleet 2012-04-04 02:32
@godofleet - since you're new here, do you know that the way StackOverflow works is that the question writer should evaluate the answers that are posted and, if they get their question answered, they should select an answer as the "best answer" by clicking the checkmark to the left of the answer. This rewards the answerer with some reputation points, gives you some reputation points for following the proper StackOverflow protocol and shows future readers which answer was the best for you. Once you have a few more reputation points, you can also upvote all answers that were helpful - jfriend00 2012-04-04 02:41


I think it may have to do with jQuery setting the spans to display: block during some point in the animation. If you set .flipper {display: inline !important} it seems to work for me.

2012-04-04 01:08
by powerbuoy
i actually tried this solution a while ago and thought it was working too however it breaks the smooth sliding animation for some reason... I think something about how jquery animate works requires block level elemnts or at least inline-block - godofleet 2012-04-04 02:33