Why is the positioning of inline-block elements so freakishly content-dependent?

I’m making the layout for a new site. I simply want a horizontally centered trunk container, with in it the navigation menu div and the article div side by side. Inspired by http://www.sitepoint.com/give-floats-the-flick-in-css-layouts/, I thought I’d use inline-block for the two (child) divs, for a change. Only to see a behavior – from IE8 to Chrome35 – that I can’t get my head around.

Here is the bare-bones demo, consisting of this code:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo Behavior inline-block</title>
<style>
#trunkContainer {
    width: 300px;
    margin: auto;
    border: 1px solid black;
}
#navMenuDiv {
    width: 100px;
    height: 100px;
    background: yellow;
    display: inline-block;
}
#articleDiv {
    width: 200px;
    height: 100px;
    background: aqua;
    display: inline-block;
}
</style>
</head>
<body>
    <div id="trunkContainer"><div id="navMenuDiv"></div><div id="articleDiv">ABC</div></div>
</body>
</html>

I made the divs code one line, to eliminate the influence of spaces, tabs and hard returns in the code.

Just remove the ABC, or move it from the articleDiv to the navMenuDiv, and see that the positioning of inline-block elements is strongly – I’d say freakishly – content-dependent. My first question is: Why such behavior? I looked up the W3C specifications, which say: “(Inline-block) causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.” But that doesn’t make it any clearer for me.

My second, and more important question is: Does this mean that to get two block-level elements with different content types side by side there are still only two options: floating and absolute positioning, in this case relative-absolute positioning (relative to the trunkContainer)? Because only if the two (child) divs in this example contain the same type of content, are they positioned side by side.

Hi,

You just need to set the vertical-alignment of the inline-block element.

Set both to ‘vertical-align:top’ to have their top edges align or set to middle if you want the middle to align. The default is ‘baseline’ which means that when you have no text in one of the boxes the baseline is effectively the bottom of that empty element and aligns as per your demo.

As a general rule you should always set the vertical alignment when using inline-block because browsers may default to different positions anyway.

Wow! Such simple principle, with such great consequences. Thanks, Paul. :slight_smile:

I never realized that, even though I had already used inline-block on several occasions in the past. But apparently only in settings where the vertical alignment didn’t matter.

Yes, most times you could probably get away without knowing the implications but its when you do something different it makes you wonder for a while :slight_smile: