I have the following HTML:

    <ul>
        <li>
        <div>first</div>
        </li>
        <li>
        <div>first</div>
        </li>
        <li>
        <div>first</div>
        </li>
        <li>
        <div>first</div>
        </li>
    </ul>

and the following css rules:

        ul {
            padding: 0;
            border: solid 1px #000;
        }
        li {
            display:inline-block;
            padding: 10px;
            width: 114px;
            border: solid 1px #f00;
            margin: 0;
        }

        li div {
            background-color: #000;
            width: 114px;
            height: 114px;
            color: #fff;
            font-size: 18px;
        }

For some strange reason, the list items appear with a margin around them in both Firefox and Chrome. Looking at firebug, the list items do not have any margin at all, but there seems to be a void space between them.

If I later on add more list items via javascript using

$('<li><div>added via js</div></li>').appendTo($('ul'));

the "margin" doesn't appear around the new elements:

Any idea of what the hell's happening here?

Solution 1

This is caused by the display: inline-block;

li {
    display: inline-block;
    padding: 10px;
    width: 114px;
    border: solid 1px #f00;
    margin: 0;
}

Change it to float: left;.

I thought it was the padding but took a closer look and turns out it was the display :)

Example here.


After further research I have discovered that inline-block is a whitespace dependent method and renders a 4px margin to the right of each element.

To avoid this you could run all your lis together in one line, or block the end tags and begin tags together like this:

<ul>
        <li>
            <div>first</div>
        </li><li>
            <div>first</div>
        </li><li>
            <div>first</div>
        </li><li>
            <div>first</div>
        </li>
</ul>

Example here.

Hope that helps :)

Solution 2

I found a very good trick to overcoming this very same issue. My list items in my top menu had whitespace margins between each after i dropped "float:left;" in favor of "display:inline-block;".

Try setting your font-size for the unordered list to "0", ie:

ul { font-size:0; }
li { font-size:18px; }

Worked for me.

Solution 3

Seeing this post and the answers given, I thought I would explain what's going on here. This is not a bug, but is actually the intended behavior of inline-block.

The best way to illustrate why this is the correct behavior is with smileys in a paragraph:

<p>
  Hi, really glad to hear from you yesterday 
  <img src="annoying_smiley.gif"/><img src="annoying_smiley.gif"/>.
</p>

Images are, by default, displayed as inline-block (IE: a block element which obeys the inline flow - much like a single character of text). In this case you would want the two smileys to butt up next to each other, but you would still want a space between 'yesterday' and the first smiley.

Hope this explains it, and also explains why inline-block has taken so long to be fully supported; There aren't actually many use-cases for using it as intended.

To answer your question, your best bet would be to do this:

ul {
  height: some set height
       /* OR */
  overflow-y: auto;
}

ul li {
  float: left;
}

Solution 4

In my opinion and in this case the best thing to do is to remove the letter spacing of the li's parent and re-put it on the li!

So your CSS rule:

ul{
    padding: 0;
    border: solid 1px #000;
    letter-spacing  :-4px; /*Remove the letter spacing*/
}
li{
    display:inline-block;
    padding: 10px;
    width: 114px;
    border: solid 1px #f00;
    margin: 0;
    letter-spacing  :0px; /*Put back the letter spacing*/ 

}

Solution 5

Remove all </li> tags. I don't know why but this fixes your margin problem.

<ul>
    <li>
        <div>first</div>
    <li>
        <div>first</div>
    <li>
        <div>first</div>
    <li>
        <div>first</div>
</ul>

Solution 6

I just found out the reason why this happens. It appears that when using inline-block, any whitespace inside the element is rendered.

So instead of writing

    <li>
    <div>first</div>
    </li>
    <li>
    <div>first</div>
    </li>

I should write:

        <li>
            <div>first</div>
        </li><li><div>first</div>
        </li><li>....

Leaving no spaces between a li and it's closing tag. The reason why this space wasn't appearing when appending via js is because the appendTo method has all the tags without any whitespace between them. Yeah, this sucks but it's the only solution if I don't want to use float:left.

Solution found here

Solution 7

Changing display: inline-block to display: table-cell also removes the space.

    li {
        display: table-cell;
        padding: 10px;
        width: 114px;
        border: solid 1px #f00;
        margin: 0;
    }

Solution 8

I found the answer to this question here: http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

He says:

"...theres one giant drawback [to inline-block]. That is, since the elements become rendered inline, white-space in your HTML code will affect the rendering. That means, if we have space between the LI elements in our code, it will render a 4 pixel margin to the right of each element."

So the solution is to remove the line breaks between inline-block elements.

  <ul>
    <li><a href="#">Make</a></li>
    <li><a href="#">Love</a></li>
    <li><a href="#">Not</a></li>
    <li><a href="#">War</a></li>
  </ul>

Becomes...

<ul>
    <li>
      <a href="#">Make</a>
    </li><li>
      <a href="#">Love</a>
    </li><li>
      <a href="#">Not</a>
    </li><li>
      <a href="#">War</a>
    </li>
</ul>

And the pesky margins disappear.

Solution 9

Try this solution:

    <ul><!--
        --><li><div>first</div></li><!--
        --><li><div>first</div></li><!--
        --><li><div>first</div></li><!--
        --><li><div>first</div></li><!--
    --></ul>

Solution 10

Try changing your 'display: inline-block' to 'float: left'. The separation that you are seeing then disappears. Here is a jsFiddle for you to play with:

http://jsfiddle.net/rcravens/XD9SD/

Bob