Discover the secret lies within the display method, with no clear correlation to the height values due to differing calculations in each case.
For inline elements in the first scenario, expect the 'height' property not to apply as the content area's height is based on font properties such as the em-box or maximum ascender and descender. The vertical padding, border, and margin for an inline non-replaced box start at the top and bottom of the content area, unrelated to line-height calculations.ref
The span's height depends solely on font properties (font-family, font-size) along with the border top/bottom. Without delving into specific font details, it becomes challenging to pinpoint the exact calculation method.
Related:
Can specific text character change the line height?
What determines the space between the highest and lowest letter and the top and bottom border of the element the letter's in?
In the second instance, the span evolves into a block element through the use of position:absolute
. Following the rule here: https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height, the height now equals the distance between the topmost and bottommost line boxes.
Thus, our element's height aligns with the line box defined by line-height
, impacted by both line-height and vertical alignment but simplified when dealing with single characters.
Adjusting the default line-height
set by the browser can yield desired height results:
const
small = document.querySelector('#small'),
large = document.querySelector('#large')
window.onclick = () => {
console.log(small.getBoundingClientRect().height,
large.getBoundingClientRect().height)
}
div {
border: solid purple 2px;
}
#small {
border: solid red 2px;
line-height:1; /* will give a height = 1*16 + 4 */
}
#large {
border: solid black 2px;
font-size: 10rem;
line-height:1; /* will give a height = 1*10*16 + 4 */
}
span {
position: absolute;
}
<div>
<span id='small'>.</span>
<span id='large'>.</span>
</div>
Related: How does height will be calculated, based on font-size?
Converting the span
element to inline-block
produces parallel behavior to the second case following rules detailed here: https://www.w3.org/TR/CSS21/visudet.html#block-root-margin, leading to identical outcomes seen with absolute elements (https://www.w3.org/TR/CSS21/visudet.html#root-height). In this context, line-height
dictates the element's height:
const
small = document.querySelector('#small'),
large = document.querySelector('#large')
window.onclick = () => {
console.log(small.getBoundingClientRect().height,
large.getBoundingClientRect().height)
}
div {
border: solid purple 2px;
}
#small {
border: solid red 2px;
display:inline-block;
line-height:1;
}
#large {
border: solid black 2px;
font-size: 10rem;
display:inline-block;
line-height:1;
}
<div>
<span id='small'>.</span>
<span id='large'>.</span>
</div>