tags:

views:

3225

answers:

2

I'm trying to put some (vertically-stacked) display:block elements within a display:inline-block element. According to the CSS specification, the inline-block element should be a containing block, so it can have display:block elements within it and those should not affect the rest of the layout.

However, the display:block elements inside the display:inline-block elements disrupt the rest of the page; so does having nothing at all within the inline-block, or even a basic element like a paragraph; only simple text avoids disruption of the rest of the page (by disruption I mean shifting other divs down, e.g. in this case the left red block moves down a line and has a blank white space above it). I'm using Firefox 3.0.6.

<html><head><style type="text/css">
#left {
  display: inline-block;
  background: red;
  width: 20%;
  height: 100%;
}
#right {
  display: inline-block;
  background: green;
  width: 80%;
  height: 100%;
}
</style></head><body>
  <div id="left">Left</div><div id="right">Right</div>
</body></html>

The above shows as two panes, left red, right green, as expected. If I change "Right" to

<p>Right</p>

or remove it entirely, or (as I want to do) replace it with a couple of divs, I get the bad formatting.

Is this a Firefox bug, or am I doing something wrong, or are my expectations incorrect? (FWIW, IE 7 mangles them all equally, as if it doesn't understand inline-block; doesn't matter, this is an internal app. and I'm only using Firefox). I may be able to get the layout I want using float/margin, but I'd prefer not to have to do that.

+4  A: 

Well display: inline-block can be a bit tricky to get cross-browser. It will require at minimum, a few hacks and, for Firefox 2, potentially an extra element.

CSS

.inlineBlock { display: -moz-inline-stack; display: inline-block; zoom: 1; *display: inline; }

display: -moz-inline-stack is for Firefox 2. All the immediate children will need to have display: block or otherwise be block level elements. Note if you need your inline-block element to shrink wrap I think you can use display: -moz-inline-box instead.

zoom: 1 gives hasLayout to the element (for IE 7 and below). Part 1 of the hack needed for IE7 and below compatibilty.

*display: inline is a hack second part of the hack needed for IE7 and below compatibility.

I occasionally need to add overflow: hidden for IE compatibility as well.

For your specific situation i think what you need is:

<html><head><style type="text/css">
#left {
  display: inline-block;
  background: red;
  width: 20%;
  height: 100%;
  vertical-align: top;
}
#right {
  display: inline-block;
  background: green;
  width: 80%;
  height: 100%;
  vertical-align: top;
}
</style></head><body>
  <div id="left">Left</div><div id="right"><p>Right</p><p>Right 2</p></div>
</body></html>
Josh
I'm using Firefox 3. I don't care about Firefox 2 (or any other browser) right now. Are any of those hacks required for FF3?
FF3 should have full support.
Josh
Sorry, misunderstood, your original question.
Josh
Vertical-align:top got it. I had set vertical-align when I was playing with it earlier (still using floats then), but not in this reduction. Many thanks.
A: 

I get the bad formatting.

You are being bitten by margin collapsing, a CSS ‘cleverness’ which is a pain as often as it is a boon. The margin of the <p> collapses outwards to become a top margin on the inline-block; this then behaves as a margin would on an ‘inline’ element would, pushing the vertical-alignment of the text line out.

You can stop it happening by removing the margins from ‘p’ elements and using padding instead. Alternatively place a non-empty element with no top margin at the top of the block and one with no bottom margin at the bottom.

Is this a Firefox bug

I think possibly yes, according to the spec's:

Margins of inline-block elements do not collapse (not even with their in-flow children).

bobince