8

http://jsfiddle.net/chovy/dk5Ua/

<div></div>

var $span = $('<span>foo</span>');

$span.hide();
$("div").append($span);
$span.fadeIn();

You'll notice the resulting span has inline style display: block; instead of inline.

This is the resulting html:

<span style="display: block;">foo</span>

How do I get the fadeIn() to result in display: inline?

chovy
  • 72,281
  • 52
  • 227
  • 295

4 Answers4

14

I just found a simple solution to a similar problem. In your case, the fix would be this:

$span.css('display', 'inline').hide().fadeIn();
Shomz
  • 37,421
  • 4
  • 57
  • 85
4

I'm with Adrian; that really wasn't a question. But you are correct: jQuery does a very naive translation of display properties when you use anything that show/hides elements (eg. show, hide, togle, fadeOut, etc.).

I've honestly never understood why they do this (it'd be much simpler to simply set display to:

isShown ? '' : 'none';

instead of their logic, which is essentially:

isShown ? 'block' : 'none';

) but they have reasons for just about everything they do, so I imagine they have a some logic behind setting the wrong display types on things.

* EDIT *

As I suspected, the jQuery people did have their reasons (see the comments from jfriend00); also I see that there's an actual question in the question now:

How do I get the fadeIn() to result in display: inline?

The answer is that you need to look at how fadeIn works; essentially it's just:

this.animate({opacity: "show"}, speed, easing, callback );

In other words, it's roughly equivalent to:

this.animate({opacity: '100%'}, speed, easing, function() {
    this.css('display', 'block')
});

(WARNING: I'm not actually a big user of jQuery's animation features, so while the above code should work, I make no promises).

Given that, if you want to set the display to something else (like say 'inline'), you can do:

this.animate({opacity: '100%'}, speed, easing, function() {
    this.css('display', 'inline') // or you could use this.css('display', '')
});
machineghost
  • 33,529
  • 30
  • 159
  • 234
  • They probably can't use `isShown ? '' : 'none';` because they have to override any CSS that might be in effect and setting display to `''` would allow the CSS to be in effect rather than forcing the object to be shown. – jfriend00 Nov 08 '12 at 01:56
  • I imagine that's because inline elements, being a part of the flow, cause greater disruption when changing their display property, as they force a reflow of everything around them? I suppose you could animate a change in rgba() on the element, but that wouldn't be supported all that well across all browsers, either. – Jason M. Batchelor Nov 08 '12 at 01:56
  • @jfriend00 It doesn't "allow the CSS to be in effect" though; it replaces whatever existing value is there with `''`, which (in every browser I know) sets the property back to its default value (which will be the correct `display` type, eg. inline for spans, block for divs, etc.). – machineghost Nov 08 '12 at 17:35
  • @morei57 That might be the reason, although personally I'd rather have a few more reflows and the correct display types /shrug – machineghost Nov 08 '12 at 17:36
  • 1
    @machineghost - you didn't understand my comment. Setting `style.display=''` sets it to default which allows CSS rules in a style file specified by a selector (not set specifically on the style attribute of the object) to be in effect. Setting `style.display = 'inline'` or `style.display = 'block'` overrides the CSS rules giving a known result. There is difference and jQuery probably wants to override the CSS rules to get to a known result. – jfriend00 Nov 08 '12 at 21:49
  • @jfriend00 Ok, now I understand what you're getting at: if someone adds `div#whatever {display:none}` in a stylesheet, and jQuery uses `style.display = ''` as its show() operation, it won't work on that div. Still, it seems like jQuery could simply use `style.display = ''` as its show logic, and then check `if (!this.is(':visible')) style = 'block'`, so that it only clobbers the display style if someone used .show() on an element hidden by CSS ... but I guess there are performance implications to that. – machineghost Nov 09 '12 at 00:01
  • `There is difference and jQuery probably wants to override the CSS rules to get to a known result.` - true, but it's not really any better, as it's still the wrong result. :) – nicodemus13 Jun 04 '14 at 11:32
2

I found this extremely useful, and somewhat simpler (based on MakuraYami's answer to this question):

$span.fadeIn().css('display', 'inline');
Community
  • 1
  • 1
Chris Kempen
  • 9,491
  • 5
  • 40
  • 52
0

By cloning the original object I can call fadeIn and it gives me an inline style.

var $htm = $('<span/>')
, $divs = $('div');

$divs.replaceWith(function(){
   return $htm.clone().fadeIn(2000);
});
chovy
  • 72,281
  • 52
  • 227
  • 295