3

So I'm working on a project that involves cloning some objects and appending them to the same parent, I then animate these objects but my calculations always seemed to be off, and I realized it's because inline-block items always have trailing space, which would be fine but when I append a cloned item using jQuery to the parent div that trailing space isn't included which leaves things very inconsistent and difficult to work with.

When inspecting the elements using browser tools, the elements claim to be identical, setting margins and padding make no difference, is this a bug or am I just missing something? Below is a simple demo to replicate the results

https://jsfiddle.net/kd5opn7j/2/

$('ul').find('li').each(function(){
  $('ul').append($(this).clone());
});
li {
  display: inline-block;
  width:50px;
  height:50px;
  background: #555;
}
<ul>
    <li></li>
    <li></li>
    <li></li>
</ul>
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
keepevets
  • 57
  • 3

1 Answers1

6

The space between the boxes comes from the newlines and indentation in the markup. jQuery doesn't preserve this formatting style when appending elements because it modifies the DOM, not the markup directly, and it only appends the elements you specify.

In other words, what your markup really looks like after jQuery is done appending the new elements is this:

<ul>
    <li></li>
    <li></li>
    <li></li>
<li></li><li></li><li></li></ul>

The inspector displays elements in a hierarchical structure for presentation's sake. It does not reflect the actual (or generated) markup.

If you want to preserve the whitespace between the elements, you can cheat by appending a literal space either before or after each new element:

$('ul').find('li').each(function(){
  $('ul').append(' ').append($(this).clone());
});

Or, if you absolutely must preserve the original indentation style for some reason (which will be reflected in the parent's innerHTML)...

$('ul').find('li').each(function(){
  $('ul').append('    ').append($(this).clone()).append('\n');
});

Note that this will make no difference in rendering as all contiguous spaces and newlines will be collapsed to a single space anyway.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Ahh, i see, thanks, i've been racking my brain forever on this, changing the jsfiddle to reflect what you said proves your point – keepevets Apr 17 '15 at 17:25
  • Great observation! But your answer explain why this happens, not how to solve this issue. I'm not critizing your answer, but I'm actually curious on how to fix it. – Bruno Monteiro Apr 17 '15 at 17:26
  • 1
    @Bruno Monteiro: Yeah, just my personal answering style - I tend to avoid assuming what issue needs to be solved if the question doesn't specify one. But in this case, it's fairly easy to deduce, and since you asked nicely, I'll update my answer :) – BoltClock Apr 17 '15 at 17:29
  • Well it definitely made me feel less crazy, wasn't sure how i was going to go about putting all my items on 1 line but @adeneo gives a good fix in the comments above – keepevets Apr 17 '15 at 17:33
  • @keepevets: I'm not such a big fan of hardcoding an approximated value as a margin (you'll notice a `margin-right: 4px` in adeneo's CSS which is really what creates the space between elements in place of `font-size: 0`). Appending spaces between elements is much more natural. – BoltClock Apr 17 '15 at 17:37