views:

317

answers:

2

I have a horizontal line of div elements that are display:inline-block and top aligned.

I can add elements, and the line expands. When I remove elements by animating the width to 0, the line doesn't retain it's single line appearance, but rather forces a second line to temporarily appear during the animation.

The behavior is the same in IE, Webkit and Firefox.

I could change the interface to avoid the problem, but I still would like to know what causes it, and how to fix it if possible.

Here's a scaled-down example of the issue.

body {
    text-align: center;
}
#container {
    height: 20px;
    border: 1px dashed #AAA;
    background: #EEE;
    margin: 0 auto;
    display:table !important;
    display: -moz-inline-stack;  /* Pre FF3 fix */
    display: inline-block;
    zoom: 1;                    /* IE fix */
    *display: inline;           /* IE fix */
}
.item {
    cursor: pointer;
    width: 50px;
    height: 18px;
    border: 1px solid purple;
    vertical-align: top;
    display: inline-block;
    color: white;
    vertical-align: top;
    display: -moz-inline-stack;  /* Pre FF3 fix */
    display: inline-block;
    zoom: 1;                    /* IE fix */
    *display: inline;           /* IE fix */
}
.outer {
    background: orange;
}


$('#add').click(function() {
    $(this).before('<div class="item"></div>')
});

$('#add').click().click().click()

$('.item:not(.outer)').live('click', function() { 
    $(this).animate({width: 1, paddingLeft: 0}, 1000, function() {$(this).remove()}); 
});

<div id="container"><div class='item outer'></div><div id="add" class="item outer">Add</div></div>
+1  A: 

Maybe it is related to the fact that jquery has to convert it to a block element when animating its width? This other question might shed some light

F.Aquino
I did glance at that one, and assumed jQuery was probably changing the 'display' property. Just not sure why it would need to be changed in the case of an inline-block. Is it possible to avoid/override that behavior?
patrick dw
I see a problem with browser support, they try to keep the animation as cross as possible and some older agents don't support it. Maybe the solution in the link with the extra html will do it with minimum collateral damage?
F.Aquino
Thank you for your help. I decided to modify jQuery just a little, and it works well. I've posted my solution if you're interested. **Thanks again.**
patrick dw
+1  A: 

Well, here's my solution if anyone is interested.

I ended up modifying jQuery's source just a little, and it seems to work well. Then I slipped the changes into the minified version with the necessary tweaks.

Here's what I did (for the non-minified):

In jQuery's animate: function, in the if() statement that checks for 'height' and 'width', I added the following:

// Detect inline-block standard, pre ie8 fix, and pre Firefox 3 fix
opt.ibCheck =(jQuery.css(this,'display') === 'inline-block') || 
            (jQuery.css(this,'zoom') !== 'normal' && jQuery.css(this,'display') === 'inline') || 
            (jQuery.css(this,'display') === '-moz-inline-stack');

Then in jQuery.fx.prototype.update:, in the if() statement that checks for 'height', 'width' and 'this.element.style', I changed that if() statement to the following:

if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style && !this.options.ibCheck ) {

...checking for the ibCheck property that was set in 'animate'.

Everything seems to work well. It checks for inline-block, the common pre-Firefox 3 fix or the pre-ie8 fix. If one is found, it sets ibCheck to 'true'. The update() function will not change the display to 'block' if ibCheck is 'true'.

There could be a better check for IE. I suppose if someone animates an 'inline' element, with 'zoom' set to anything besides 'normal', it may cause problems? As for me, I didn't know that IE even accepted a 'zoom' attribute until yesterday!

patrick dw
Yes! Thanks for the solution. There's a similar solution on this page http://forum.jquery.com/topic/animate-does-not-play-well-with-css-display-box-and-inline-block-as-well, but I prefer yours because it caches the test result. By the way, I hope this gets fixed in jQuery, so that we don't have to deploy hacked versions. :)
harpo
@harpo - You're welcome. Worth an up-vote perhaps? ;o) I haven't gotten around to it, but you could place the modified methods in a separate file so that jQuery's are overridden. Then you can still use a CDN version of jQuery.
patrick dw
Yes, thanks. You also answered my next question, about separating the mods to use a CDN. I'm trying that out now.
harpo
@harpo - Thanks! And let me know how it pans out for you.
patrick dw