What Is The Definition of "The Baseline of Parent Box"

Why does the sibling line-box gets aligned vertically whenever there is no space for the first line-box to be vertically aligned?

Now, if i apply 'vertical-align' to the second line-box, it moves without a problem, since there is plenty of space. However, obviously there is no space for the first line-box to move up or down, but when i apply vertical-align to it, the second line-box moves almost as if the vertical align properties applies to it.

Your missunderstanding is in the plenty of space or let's say space in general. Vertical align will not consider the space you have in mind but will create that space.

let's first understand the definition

This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element. ref

Then you can read the following rules:

The height of a line box is determined as follows:

  1. The height of each inline-level box in the line box is calculated. For replaced elements, inline-block elements, and inline-table elements, this is the height of their margin box; for inline boxes, this is their 'line-height'.

  2. The inline-level boxes are aligned vertically according to their 'vertical-align' property. In case they are aligned 'top' or 'bottom', they must be aligned so as to minimize the line box height. If such boxes are tall enough, there are multiple solutions and CSS 2.1 does not define the position of the line box's baseline (i.e., the position of the strut, see below).

  3. The line box height is the distance between the uppermost box top and the lowermost box bottom.

We first start by defining the height of each element and we consider the margin box then we place all the elements and only at end the line box height is defined (the spaces you are talking about).

In your first example, both element have a default baseline alignment

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.

so both will get aligned by their text and logically the margin of any of them will push the other.

A better example with different fonts:

.container {
border: 1px solid;
background:linear-gradient(blue,blue) 0 78px/100% 2px no-repeat;
}

.first {
display: inline-block;
font-size: 30px;
background-color: darkcyan;
border: 1px solid;
margin: 50px 0 0 0;
opacity:0.5;
}

.second {
display: inline-block;
border: 1px solid;
background-color: red;
font-size: 50px;
margin:0;
opacity:0.5;
}
<div class="container">
text outside

<div class="first">Lorem ipsum</div>

<p class="second">Lorem ipsum</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>

If two sibling inline elements are marked with vertical-align, what's the font serving as baseline?

From the specification:

The following values only have meaning with respect to a parent inline element, or to the strut of a parent block container element.

And

On a block container element whose content is composed of inline-level elements, 'line-height' specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut." (The name is inspired by TeX.).

So it's like we always have a kind of text having 0 width inside our container that will define the baseline.

.box {
background:linear-gradient(red,red) 0 22px/100% 1px no-repeat;
}

.box > * {
outline:1px solid;
}
With text
<div style="padding: 8px 16px; background-color: green" class="box">
BASELINE
<div style="display:inline-block;font-size:18px;vertical-align:text-top">Hello</div>

<div style="display:inline-block;font-size:72px;vertical-align:text-top">Help</div>
</div>
without text (the reference is the same)
<div style="padding: 8px 16px; background-color: green" class="box">
<div style="display:inline-block;font-size:18px;vertical-align:text-top">Hello</div>

<div style="display:inline-block;font-size:72px;vertical-align:text-top">Help</div>
</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.

Child element's text is not aligned with parent's element text in Chrome when parent element has vertical-align: top

After reading CSS 2.1 specification (W3C Recommendation 07 June 2011) it seems to me that both Chrome and Firefox are correct and they are free to choose different baselines.

Section 9.2.2. defines what an inline-level box is.

9.2.2 Inline-level elements and inline boxes

Inline-level elements are those elements of the source document that
do not form new blocks of content; the content is distributed in lines
(e.g., emphasized pieces of text within a paragraph, inline images,
etc.). The following values of the 'display' property make an element
inline-level: 'inline', 'inline-table', and 'inline-block'.
Inline-level elements generate inline-level boxes, which are boxes
that participate in an inline formatting context.

An inline box is one that is both inline-level and whose contents
participate in its containing inline formatting context. A
non-replaced element with a 'display' value of 'inline' generates an
inline box. Inline-level boxes that are not inline boxes (such as
replaced inline-level elements, inline-block elements, and
inline-table elements) are called atomic inline-level boxes because
they participate in their inline formatting context as a single opaque
box.

Section 9.4.2 defines what a line box is.

9.4.2 Inline formatting contexts

In an inline formatting context, boxes are laid out horizontally, one
after the other, beginning at the top of a containing block.
Horizontal margins, borders, and padding are respected between these
boxes. The boxes may be aligned vertically in different ways: their
bottoms or tops may be aligned, or the baselines of text within them
may be aligned. The rectangular area that contains the boxes that form
a line is called a line box.

Then section 10.8 mentions:

The inline-level boxes are aligned vertically according to their
'vertical-align' property. In case they are aligned 'top' or 'bottom',
they must be aligned so as to minimize the line box height. If such
boxes are tall enough, there are multiple solutions and CSS 2.1 does
not define the position of the line box's baseline (i.e., the position
of the strut, see below).

This seems to apply to the code at http://jsfiddle.net/ePBZz/. In this code, vertical-align: top has been applied to the div id="y" which has been defined as follows.

<div id="y">Bar <span>Baz</span></div>

There are two inline-level boxes in this element. The two inline-level boxes are:

  1. Anonymous: "Bar"
  2. SPAN: "Baz"

Now it is not clear what it really means for inline-level boxes to be tall enough, but if we assume that these two inline-level boxes are tall enough, then as per the last quoted text, the standard does not define the baseline of the line box that contains these two inline-level boxes. As a result, Chrome and Firefox are free to choose different baselines and align the baseline of the second inline level-box (SPAN: "Baz") with these differently chosen baselines, thereby producing different outputs.

inline-block element nested in another inline-block element has an offsetTop

To fix the problem you need to add vertical-align:top to #leftBox or #rightBox

The reason is that the default vertical-align value is baseline which

Aligns the baseline of the box with the baseline of the parent box

The baseline of the parent box is the bottom of the box.

Baseline is defined as

the line upon which most letters "sit" and below which descenders extend

All the cases you describe in the question result in the baseline being altered which aligns the elements as desired.

A good example of the baseline is the following code in which there are no elements in your wrapper <div> but very large font-size text instead. You can see how the bottom of the green <div> is aligned to the baseline of the parent (the red dotted border <div>) and how the pink <div>s text makes it move to where the text it sitting on the parent baseline.

<div style="height:300px;width:500px;font-size:0;border:1px dotted red">
<div style="display: inline-block; background: pink; width: 50%; height: 100%;">
<div style="height:100%;font-size:150px">foo</div>
</div>
<div style="display: inline-block; background: green; width: 50%; height: 100%;"></div>
</div>


Related Topics



Leave a reply



Submit