Difference Between Baseline of Empty and Non-Empty Inline Blocks

Difference between baseline of empty and non-empty inline blocks

From CSS2: Line height calculations

vertical-align: baseline — align the baseline of the box with the baseline of the parent box. If the box doesn't have a baseline, align
the bottom of the box with the parent's baseline.

inline-block with empty content makes layout disordered (vertical alignment)?

use 'vertical-align: middle;' to the inline-block element


vertical-align: middle;

http://jsbin.com/ajexab/1/edit

parent div height is incorrect when it contains another empty div with display: inline-block,

It's by design and is related to the baseline alignment. To understand what is happening add more text inside your container

why parent div height is larger than child div?
<div style="background-color:red;">
<div style='background-color:blue; width:32px; height:32px; display:inline-block'></div>
p
</div>

<hr>

adding any content fixes sizing
<div style="background-color:red;">
<div style='background-color:blue; width:32px; height:32px; display:inline-block;color:#fff'>
x
</div>
p
</div>

& nbsp; works too

<div style="background-color:red;">
<div style='background-color:blue; width:32px; height:32px; display:inline-block;color:#fff'> </div>
p
</div>

Why baseline of `inline-block` element with `overflow:hidden` is set to its bottom margin?

1. What the reason to change baseline of inline-block element from baseline of its line box to bottom margin edge?

The baseline of an 'inline-block' is changed to its bottom margin edge when its overflow property is set to hidden (full specification here).

As for the reason for this decision, I think since the overflown part is hidden, user agents (browsers) may choose to render that overflown part and not display it, or choose to not render it at all. And when the overflown part is not rendered, user agents have no way to tell the baseline of its last line box, as it is not rendered, where it goes is not known.

If the baseline of 'inline-block' whose overflow is set to hidden is still kept as the baseline of its last line box, user agents are forced to render what is hidden to user, which may hinder performance, or at least, put extra restrictions on user agents. What's more, in such case, other inline texts in the same line box are aligned to such a baseline where texts around the overflow-hidden inline-box is hidden, which is kind of stange and not intuitive.

I made a simple demo emulating that inline-block with overflow hidden still has its baseline set to the baseline of its last line box.

emultaing_imaginary_baseline_of_overflow_hidden_inline_block

var isOverflowHidden = false;document.querySelector('button').onclick = function() {  document.getElementById('inline-box').style.overflow = isOverflowHidden ? '' : 'hidden';  isOverflowHidden = !isOverflowHidden;}
html { background: white; }#inline-box { display: inline-block; height: 18px; }.overflown { color: white; }
<p><button id="toggle">Toggle 'overflow: hidden;' on 'inline-block'</button></p>
<span> texts sit <span id="inline-box"> texts in inline-block <br> <span class="overflown"> line 2 <br> line 3 </span> </span> on baseline</span>

Why my inline-block divs are not aligned when only one of them has text?

This is the consequence of the "baseline" vertical alignment in CSS. From the CSS 2.1 spec, section 10.8 Line height calculations: the 'line-height' and 'vertical-align' properties

baseline


Align the baseline of the box with the baseline of the parent box. If the box
does not have a baseline, align the bottom margin edge with the parent's baseline.
(my emphasis)

Because the default alignment for the inline-blocks is "baseline", unless it is overridden, this rule applies. When text is put in the inline-block, that text will create a baseline for the inline-block and the first (non-bolded) sentence applies.

When there is no text in the inline-block, then it has no baseline and so the second (bolded) sentence applies.

In the JSFiddle here: http://jsfiddle.net/WjCb9/1/ I have removed from your example the margin:1em which was creating (at least for me) a misleading illusion, and added the text baseline to show where the baseline of the containing box is. The baseline is along the bottom of the word "baseline", so you can see that the empty inline-block has its bottom margin edge aligned with the parent's baseline as required by the CSS rule above.

Why a div with an empty inline-block has height?

But when the span display is 'inline', why the div's height are 0?

Not 100% correct because if the span has at least one character the height will be different from 0. Even an invisible zero width space:

div {
background: red;
}
<div><span>​</span></div>

Understanding CSS2.1 specification regarding height on inline-level boxes

Is the height of inline-level boxes equal to the line-height property set on them (with the minimum being the line-height set on the parent block container element),

Yes it is.

OR is it just determined by the font height (and UA implementation)?

No it isn't

CSS is really about boxes, not elements, and you should try not to confuse the two.

So an inline element has associated with it a number of boxes. A content box, padding box, border box and margin box. It also has zero (if display:none), one, or multiple inline boxes. The content box, paddings, borders and margins may be divided among the inline boxes so that the inline content can be spread over more than one line.

The inline box's height is the content height adjusted by the leading. It's the leading that does the magic here. The leading is defined as the line-height of the element minus the content height of that inline box.

Simply rearranging that equation tells us that the height of the inline box depends only on the line-height and not on the content box (or padding, border, margin boxes).

Note that none of the above discusses the line box, which is a different thing again and not a direct property of inline elements or their boxes. The line box is constructed by arranging the inline boxes that occur on the same line such that their vertical alignments fit the rules computed for the elements, including the zero width inline box formed by the strut.

Each line box is bounded by the top of uppermost inline box and the bottom of the lowestmost inline box that that line box contains.


Digression: On why the height of the line box can surprise.

Suppose we have a simple case of a containing block which just contains one short inline element (i.e. short enough that it fits in a single line box). Also suppose that everything is aligned on the baseline. Let's say that the line-height is set on the containing box to 20px, and the inline element inherits that. Also suppose that the font-size (em-square) of the containing block is 16px, and that means that the font metrics compute to an ascent (above the baseline) of 14px and a descent (below the baseline) of 4px.

So the content area for the strut is (14px + 4px =) 18px high. The line-height is 20px, so there is 2px leading, 1px goes above the ascent, and 1px below the descent. So the line-height of the strut is made of 15px above the baseline and 5px below the baseline.

Now, suppose that the font-size of the inline element is set to 0.5em (i.e. half that of the containing block). The content area for the inline element will be an ascent of 7px and a descent of 2px. The line-height is still 20px, so the leading is 20px - (7px + 2px) = 11px, meaning that 5.5px goes above the ascent and 5.5px goes below the descent. This results in the line-height for the inline element is made of 12.5px above the baseline and 7.5px below the baseline.

Since the strut and the inline element are aligned vertically to their baselines, the top of the uppermost inline box (the strut) is 15px above the baseline and the bottom of the the lowermost inline box (the inline element) is 7.5px below the baseline, the actual height of the line box is not 20px but (15px + 7.5px =) 22.5px.



Related Topics



Leave a reply



Submit