3

Please run the demo:

* {
  margin: 0;
  padding: 0;
}

.body {
  font-family: Microsoft Yahei;
  font-size: 16px;
  background-color: lightblue;
  height: 400px;
  width: 400px;
  line-height: 2;
  vertical-align: baseline;
}

.body span {
  background-color: pink;
}

.body .inline-block {
  display: inline-block;
  background: orange;
  height: 50px;
}

.inline-block.text {
  vertical-align: text-top;
}
<div class="body">
  <span>
words-g words words-g
  <span class="inline-block text">with inline-block box child</span> words-g w
  </span>
</div>

The point is that I set

.inline-block.text {
  vertical-align: text-top;
}

According to the specification:

In the following definitions, for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height' (containing the box's glyphs and the half-leading on each side, see above). For all other elements, the box used for alignment is the margin box.

and in the section 'line-height':

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,in this case,.inline-block.textis a

  • block container element whose content is composed of inline-level elements
  • whose height is 50px and line-height is 32px
  • also is an inline non-replaced elements

And here is my question:

the box used for alignment is the box whose height is the 'line-height'

  1. What is the above box point at in this case for .inline-block.text?

As the demo shows,I think it is the box with height 50px. However,the box's height is not the line-height which conflicts with the specification above. So,I was confused and don't understand the above sentence in the specification.

  1. And if you think the above box is the box with height 50px,how do you explain the fact that height 50px is not the line-height 32px?

Please notice:

  • I just want to understand this sentence which is the box used for alignment is the box whose height is the 'line-height',so I can understand the vertical-align better.

  • I am not asking for a specific solution.

Whatever thanks for your help!

Community
  • 1
  • 1
xianshenglu
  • 4,943
  • 3
  • 17
  • 34

2 Answers2

1

The statement

for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height'

does not apply to inline-blocks. Inline-blocks are not inline elements. Inline elements are elements with display: inline, and generate inline boxes. Inline-blocks are not inline boxes, but inline-level (the "-level" part is important!) block container boxes. Therefore, the statement

For all other elements, the box used for alignment is the margin box.

applies instead, which results in vertical-align: text-top causing the top outer edge of the inline-block to align with the top of the line box.

Any part of the specification that is said to apply to inline elements does not apply to inline-blocks.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • I was hoping you are right because that will make a lot of questions clear.However,I didn't find any definition of `inline element`.So,where did you find this:`Inline elements are elements with display: inline, and generate inline boxes.`? – xianshenglu May 20 '18 at 13:02
  • @xianshenglu: In the prose for line-height, in the sentence "On a non-replaced inline element, 'line-height' specifies the height that is used in the calculation of the line box height.", the word "inline" links to section 9.2.2. Section 9 uses "inline element" and "inline box" interchangeably, except that the difference between an element and a box is that an element may generate one or more boxes, which is a separate topic altogether. – BoltClock May 20 '18 at 13:04
  • Feels like a word game. I hate it ! I will check and try to find a definition in the specification or something like that. Anyway,thanks for your help. It may take me a few time to finish this question. – xianshenglu May 20 '18 at 13:22
  • @xianshenglu: Yeah, I agree that the spec needs to be a little more consistent in its word usage. – BoltClock May 20 '18 at 13:32
  • According to [box-tree](https://www.w3.org/TR/css-display-3/#css-box-tree). Maybe we can think like that inline box is corresponding with inline element and inline-level box is corresponding with inline-level element . Agree? – xianshenglu May 23 '18 at 01:45
0

I guess you are confusing about the reference of the alignment (it aligns relatively to what?).

I will try to explain this with easy words. When using vertical-align with an element a you align it relatively to its parent element b whataver is the height of a (b is the reference). Using correct words it's like this:

The vertical-align property can be used in two contexts:

To vertically align an inline element's box inside its containing line box. For example, it could be used to vertically position an <img> in a line of text.ref

So the a element is the inline element's box and the b element is the containing line box and the height of b is defined by it's line-height as you already read in the specification.


Now let's consider your code and add properties step by step.

Initially let's remove the inline-block

.body {
  font-family: Microsoft Yahei;
  font-size: 16px;
  background-color: lightblue;
}

.body span {
  background-color: pink;
}

.body .inline-block {
  background: orange;
}

.inline-block.text {
  vertical-align: text-top;
}
<div class="body">
  <span>
words-g 
  <span class="inline-block text">inline-block</span> words-g w
  </span>
</div>

As you can see the inner span has the same height/line-height as the outer span and both are using the same font-family. So logically we see nothing when using text-top as vertical alignment.

Now let's add line-height:2 to the container:

.body {
  font-family: Microsoft Yahei;
  font-size: 16px;
  background-color: lightblue;
  line-height:2;
}

.body span {
  background-color: pink;
}

.body .inline-block {
  background: orange;
}

.inline-block.text {
  vertical-align: text-top;
}
<div class="body">
  <span>
words-g 
  <span class="inline-block text">inline-block</span> words-g w
  </span>
</div>

In this situation, both span will inherit the line-height:2 thus the computed value will be 32px (2 * font-size) and this will make the top reference different from text-top. To remind about this, here is a figure I shared with your beforeref:

Location of the baseline on text

And if we read the definition about the value text-top of vertical-align:

Aligns the top of the element with the top of the parent element's font.

So the top of the inner span will align with the text-top of the outer span, that's why it moved to the bottom. Then the height of the main container .body will not be equal to 32px but it will be bigger because it will consider the movement of inner span (we will have 37px).


Now let's add inline-block to the inner element:

.body {
  font-family: Microsoft Yahei;
  font-size: 16px;
  background-color: lightblue;
  line-height:2;
}

.body span {
  background-color: pink;
}

.body .inline-block {
  background: orange;
}

.inline-block.text {
  vertical-align: text-top;
  display:inline-block;
}
<div class="body">
  <span>
words-g 
  <span class="inline-block text">inline-block</span> words-g w
  </span>
</div>

The first thing you will notice is that the text didn't move BUT the orange background is covering a bigger height. This is because our element will behave as block container and this height is the line-height of the text (32px) which is also the distance between the top and bottom in the image above (Initially it was covering from text-bottom to text-top).

It's also like the blue background of the .body element since this one is a block element. Try to make the .body element inline and see what will happen.

Now you can also add a specific height to the element and nothing will change because we align relatively to the parent element. You can also play with all the vaues of vertical-align to see the different behaviors:

.body {
  font-family: Microsoft Yahei;
  font-size: 16px;
  background-color: lightblue;
  line-height:2;
  margin:5px;
}

.body span {
  background-color: pink;
}

.body .inline-block {
  background: orange;
}

.inline-block.text {
  display:inline-block;
  height:50px;
}
<div class="body">
  <span>
Align the 
  <span class="inline-block text" style="
  vertical-align: text-top;">top of this</span> with text-top
  </span>
</div>

<div class="body">
  <span>
Align the 
  <span class="inline-block text" style="
  vertical-align: top;">top of this</span> with top
  </span>
</div>

<div class="body">
  <span>
align the 
  <span class="inline-block text" style="
  vertical-align: text-bottom;">bottom of this</span> with text-bottom
  </span>
</div>

<div class="body">
  <span>
align the 
  <span class="inline-block text" style="
  vertical-align: bottom;">bottom of this</span> with bottom
  </span>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks for your answer. But I think you miss the point I was asking. You can see the another answer which is what I want. However, he didn't find the specific definition. And I am asking css working group for the definition of `inline-element` right now. – xianshenglu May 21 '18 at 01:17