#a {
display: inline-block;
}
#b {
float: left;
}
#c {
display: block;
overflow: hidden;
}
<span id="a">
<span id="b">b</span>
<span id="c">c1 c2</span>
</span>
On Chrome and IE, this gets rendered as:
However, Firefox renders this as:
You can try it in this jsFiddle.
Here is just a little bit of context, without which what I'm trying to do above might seem crazy. I intend to use the above blocks for a label, like:
The elements #a
, #b
, and #c
correspond to:
The CSS is designed to deal with the following constraints:
#a
is clickable, and I don't want it to expand to the right more than is necessary, hence the inline-block
. But obviously, another way to do the same would work.#c
must wrap if it become too long, and shouldn't go "below" block #b
, as shown below. This explain the overflow: hidden
or display: table
.Don't mix, embrace the table!
"Fixes" it on Firefox (tested 31.2.0) and IE 8, and is honestly more semantically correct.
.a{ display:inline-table; max-width:45%; }
.b{ display:table-cell; padding-right:5px;}
.c{ display:table-cell; }
<span class="a">
<span class="b">b</span>
<span class="c">c1 c2</span>
</span>
<br /><hr /><br />
<span class="a">
<span class="b">longer</span>
<span class="c">Bacon ipsum dolor amet excepteur laboris irure, corned beef minim pastrami venison in anim incididunt strip steak ea non doner.</span>
</span>
The problem with your original code is that Firefox takes the floated element completely out of flow when calculating its shrink-to-fit sizing. While float
s affect in-flow content width, they themselves are not in-flow, and thus, are merely taking the horizontal space from the rest of the content- causing the behavior you were seeing
Here is a demonstration of what is happening (view in Firefox to actually see it). Note that outline
s are used on .a
and .c
but a thick border
(which actually takes up space) is used on .b
.
.a { display: inline-block; outline: 1px solid blue; }
.b { float: left; border: 5px solid green; }
.c { display: table; outline: 1px solid red; }
<span class="a">
<span class="b">b</span>
<span class="c">c1 c2</span>
</span>
<br />
<span class="c">c1 c2</span>
This is by design, not a bug, and checking the current spec, the basic box model working draft, and the spec regarding calculating widths you'll find that floats are noted as out-of-flow, and the spec regarding block-formatting and inline-formatting explicitly states that float
s are part of an inline-context width, but does not for a block-context (the inside of an inline-block
). Thus, Firefox is actually behaving according to a strict interpretation of the spec- this is technically a bug in the other browsers.
Yet, there is still an issue with how Firefox does this.
If we make the float larger than our in-flow content (and switch back to borders as outlines include overflowing children; I've shifted the sibling red left by 1px so it will line up with its nephew clone) (again, view in Firefox)
.a { display: inline-block; border: 1px solid blue; }
.b { float: left; border: 5px solid green; width:200px; }
.c { display: table; border: 1px solid red; }
.d { position:relative; left:1px; }
.e { max-width:100px; }
<span class="a">
<span class="b">b</span>
<span class="c">c1 c2</span>
</span>
<br />
<span class="c d">c1 c2</span>
<br />
^^^ without <em>.a</em> having a width limit
<hr />
vvv with <em>.a</em> having a width limit
<br />
<span class="a e">
<span class="b">b</span>
<span class="c">c1 c2</span>
</span>
<br />
<span class="c d">c1 c2</span>
The blue box is stretched to contain its entire green child, even though, according to the strict interpretation of the spec, it is supposed to overflow instead. THIS is a bug with Firefox, as floats are only supposed to affect parent width:auto
in an inline context. In a block context, which the inside of an inline-block
is supposed to be, the width of floats is not included.
Note, this is also how most other browsers behave (to a degree- Firefox will size the parent to the float
's box width, while other browsers will put the in-flow next to it if the parent can still grow), and that if you provide any width
values or limits on .a
(ala .e
in my example), you get the expected behavior (as shown) of the green float overflowing its parent (should be the case in all browsers, as all of these behavioral issues are based on width:auto
).
Many beers to Oriol (poster of the other answer)- if I didn't start arguing with him on this, I wouldn't've had a reason to actually get into the specs and figure out what was really happening. Also credit to him for pointing out Firefox did still mis-render it- that entire chunk was thanks to him.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With