Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Block element inside inline-block acting strangely in Firefox

Tags:

css

firefox

Can anyone explain this behavior in FF?

Fiddle: http://jsfiddle.net/4mrt8wq3/

<style>
    .b { display: inline-block; }
    #a { display: block; }
</style>

<div class="b">
    <label>xxxxxxxxxx</label> 
    <input type="text" id="a"/>
</div>
<div class="b">
    <label>xxxxxxxxxx</label>
    <div> / </div>
</div>

Only in firefox, the first div is positioned one line lower than the second. It works correctly in Chrome and IE (at least IE11). It's as if the block element within the inline-block is wrapping below the second element for some reason.

Using overflow: hidden on the first div fixes the problem, but the second div is then positioned slightly oddly with about 4 or 5 pixels of margin above it. Placing overflow-hidden on both causes it to render correctly.

I am not looking for a solution to the problem, as I've already found one, but I'm at a loss of explaining the behavior... Can anyone explain WHY it's doing this?

like image 461
Erik Funkenbusch Avatar asked Apr 24 '15 22:04

Erik Funkenbusch


People also ask

Can you have block elements inside inline elements?

An element that is inline elements should not contain block elements. Block elements can contain block and/or inline elements while inline elements can only contain other inline (including inline-block , such as <img> ) elements.

How do you change inline elements to block elements?

Changing element levels You can change the visual presentation of an element using the CSS display property. For example, by changing the value of display from "inline" to "block" , you can tell the browser to render the inline element in a block box rather than an inline box, and vice versa.

What are the properties of inline-block elements?

Inline-block elements are similar to inline elements, except they can have padding and margins added on all four sides. You'll have to declare display: inline-block in your CSS code. One common use for using inline-block is for creating navigation links horizontally, as shown below.

What are block elements inline elements?

A block-level element always starts on a new line and takes up the full width available. An inline element does not start on a new line and it only takes up as much width as necessary. The <div> element is a block-level and is often used as a container for other HTML elements.


1 Answers

Yes, interesting question. First we need understand that the default vertical alignment of inline-block elements is baseline, and the baseline of each such element is the baseline of the last line box in them.

In the second div with class "b", the inner div itself contains a line box to hold the '/' character. That then provides the baseline for the second div with class "b".

That baseline must align level with the baseline of the first div with class "b". The question becomes: where is the baseline of the last line box in that div?

By making the input element itself display:block, Firefox¹ takes the view that the input element is "replaced", it's contents are opaque to CSS, therefore no line box is ever created by the input element. So the last line of the first div with class "b" is the one containing the label, and that is aligned level with the line of the '/' character.

Chrome takes a different view. Chrome treats the input element as having an internal structure visible to CSS, so the innards of the element form a line box, whose baseline then becomes the baseline of the first div with class "b", and it is that which aligned level with the '/' character.

When you add `overflow:hidden', it affects the baseline of the inline-blocks such that their baselines cease to be the baseline of their last contained line box, and becomes the bottom margin edge of the element.


Which behaviour is correct is unclear. It depends on history and the somewhat adulterated notion of replaced elements. In the early days of browsers, the rendering of some elements was delegated to external systems, either the underlying operating system or a plug-in. In particular, this was true of the input element, where rendering was done by O/S calls. The O/S had no notion of CSS, so rules had to be defined to allow the effectively black boxes to interact with the rest of the page. Such elements were classified as "replaced" elements.

Note the way this is defined. There is no official list of elements that are replaced elements, an element is a replaced element if the browser chooses to delegate its rendering to a system outside the CSS world, so in theory you could have two browsers, one delegating the rendering of an element and one natively rendering it, and from the CSS rules get quite different interactions.

As browsers progressed, they stopped delegating their rendering of the input element and rendered it themselves, in the process making the renderings CSS aware. This causes a problem because extant web pages, which assume that the input elements will be rendered using the replaced elements' rules, can become unusable. If a browser allowed that to happen, it would lose market share. So for the most part, to avoid this, the browsers implement those elements' layouts to interact with the page as if they were replaced elements, even though in reality they are not.

How far they go in this respect is not well specified. The HTML5 spec does not recognise the form controls as replaced elements, and suggests that they be rendered as inline-block, which would make Chrome's behaviour correct, but there are many ways in which all the browsers including Chrome simply don't behave that way. From a backward compatibility perspective with old web content, the Firefox behaviour is more reliable.

Until the layout of form controls is specified much more tightly than is the case currently, it is impossible to conclusively say which behaviour is correct.


¹For me, IE11 behaves like Firefox. Opera 28 (blink engine like Chrome) behaves like Chrome. Opera 12 (presto engine) behaves like Firefox.

like image 186
Alohci Avatar answered Oct 06 '22 01:10

Alohci