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.

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>
Besides, you may also compare this behavior with display: none
. When that's set, clientWidth
and clientHeight
both equates to 0.
2. How to calculate this shift?
This part is much easier, since it's documented in the link you gave in the question.
I'll start from the definition of 'line-height'.
The height of the inline box encloses all glyphs and their half-leading on each side and is thus exactly 'line-height'.
That is, line-height is composed of, from top to bottom, top half-leading + height(ascent) + depth(descent) + bottom half-leading.
Height of each component can be calculated for a given font at a given size.
Basically, every font has font metrics that specify a characteristic height above the baseline and a depth below it.
Take 'Times New Roman' as an example, using FontForge, we see that it has Em Size
as 2048, HHead Ascent
as 1825, and HHead Descent
as -443. That is, 1825 / 2048 = 89.1%
of font-size contributes to the ascent, and 443 / 2048 = 21.6%
contributes to the descent.

There are also metrics starting with 'Typo', that category will be used if 'Really use Typo metrics' is checked, and the spec recommends this:
Note. It is recommended that implementations that use OpenType or TrueType fonts use the metrics "sTypoAscender" and "sTypoDescender" from the font's OS/2 table for A and D (after scaling to the current element's font size). In the absence of these metrics, the "Ascent" and "Descent" metrics from the HHEA table should be used.
Line-height minus ascent and descent is the so-called leading.
Half the leading is added above A(ascent) and the other half below D(descent).
Assuming a font-family: Times New Roman; font-size: 100px; line-height: 200px;
, we get
ascent = 100px * (1825 / 2048) = 89px
descent = 100px * (443 / 2048) = 22px
top half-leading = bottom half-leading = (200px - 89px - 22px) / 2 = 44.5px
So we see that this can be calculated. And this can also be measured on pages.
Here is another demo for you to fiddle with.
If you are asking for the shift of bottom half-leading, it's shown as space between green line and blue line in the code snippet.
If you are asking for the shift of descent and bottom half-leading, it's shown as space between red line and blue line in the code snippet.
var $ = document.querySelector.bind(document);
var fontFamily = window.getComputedStyle($('#examinee'))['font-family']
, fontSize = +window.getComputedStyle($('#examinee'))['font-size'].replace('px', '')
, containerLineHeight = +window.getComputedStyle($('#examinee'))['line-height'].replace('px', '')
, textLineHeight = $('.target').offsetHeight
, ascent = $('#examinee .baseline').offsetTop + $('#examinee .baseline').offsetHeight - $('#examinee .text-top').offsetTop
, descent = $('#examinee .text-bottom').offsetTop - $('#examinee .baseline').offsetTop
, topHalfLeading = $('#examinee .text-top').offsetTop
, bottomHalfLeading = $('#examinee').offsetHeight - 2/* borders of the container */ - $('#examinee .text-bottom').offsetTop - $('#examinee .text-bottom').offsetHeight;
$('#font-family').innerText = fontFamily;
$('#font-size').innerText = fontSize + 'px';
$('#container-line-height').innerText = containerLineHeight + 'px';
$('#text-line-height').innerText = textLineHeight + 'px';
$('#ascent').innerText = ascent + 'px';
$('#descent').innerText = descent + 'px';
$('#top-half-leading').innerText = topHalfLeading + 'px';
$('#bottom-half-leading').innerText = bottomHalfLeading + 'px';
div {
font-size: 20px;
line-height: 2;
width: 650px;
border: 1px dashed gray;
border-top: 1px solid blue;
border-bottom: 1px solid blue;
margin: 1rem 0;
overflow: hidden;
white-space: nowrap;
}
span:not([class]) {
display: inline-block;
border: 1px dashed gray;
}
.baseline,
.text-bottom,
.text-top {
display: inline-block;
width: 200%;
margin: 0 -100%;
}
.baseline {
border-bottom: 1px solid red;
vertical-align: baseline; /* the default */
}
.text-bottom {
border-bottom: 1px solid green;
vertical-align: text-bottom;
}
.text-top {
border-bottom: 1px solid green;
vertical-align: text-top;
}
#examinee {
position: relative;
font-size: 100px;
line-height: 200px;
}
<p>
Demonstrates that "overflow: hidden;" sets baseline of an inline-block element to its bottom margin.
</p>
<div>
<span class="baseline"></span>
<span class="text-top"></span>
<span class="text-bottom"></span>
<div>
<span>
<span style=""></span>
</span>
</div>
</div>
<div>
<span class="baseline"></span>
<span class="text-top"></span>
<span class="text-bottom"></span>
<div>
<span style="overflow: hidden;">
<span style="overflow: hidden;"></span>
</span>
</div>
</div>
<p>
Demonstrates the position of baseline, text-top and text-bottom. <br>
Demonstrates how "line-height" affects box sizing.
</p>
<ul>
<li>Blue lines: top and bottom borders of line boxes
<li>Red lines: baseline of texts
<li>Green lines: text-top or text-bottom of texts
</ul>
<ul>
<li>Between blue lines: the line-height
<li>Between red line and green line: ascent or descent
</ul>
<div id="examinee">
<span class="target">GgJjPpQqYy</span>
<span class="baseline"></span>
<span class="text-top"></span>
<span class="text-bottom"></span>
</div>
Measured metrics:
<ul>
<li>font-family: <span id="font-family"></span></li>
<li>font-size: <span id="font-size"></span></li>
<li>container line-height: <span id="container-line-height"></span></li>
<li>text line-height: <span id="text-line-height"></span></li>
<li>ascent: <span id="ascent"></span></li>
<li>descent: <span id="descent"></span></li>
<li>top half-leading: <span id="top-half-leading"></span></li>
<li>bottom half-leading: <span id="bottom-half-leading"></span></li>
</ul>
