Unwanted margin in inline-block list items [duplicate]

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:

Unwanted margins

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>