Understanding CSS2.1 specification regarding height on inline-level boxes
Solution 1:
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.
Solution 2:
As I explained in this previous question (Why is there space between line boxes, not due to half leading?) we have the content area and the line box.
The content area is defined by the font properties and the UA (like described in your first quote) and the line box is defined by the line-height (like described in your second quote). Here is some example to show different height of content area based on different fonts and to illustrate the difference with the line box:
span {
border-left: 1em solid red;
background: rgba(255, 0, 0, 0.2);
}
.container>div {
margin-bottom: 5px;
border: 1px solid;
line-height: 30px;
}
.container>div:nth-of-type(1) span{
font-family: arial;
font-size: 25px;
}
.container>div:nth-of-type(2) span{
font-family: "open sans";
font-size: 20px;
}
.container>div:nth-of-type(3) span{
font-family: monospace;
font-size: 30px;
}
.container>div:nth-of-type(4) span{
font-family: cursive;
font-size: 22px;
}
<div class="container">
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
</div>
As you can see the background and border apply to the content area that is defined by the font-family
and font-size
. For all the cases, I set the line-height
to be equal 30px
thus all the line boxes are equal.
We can also notice that the border-left
behave differently which indicates that indeed the height of the content area depends on the font and UA.
Here is the same example with some vertical padding/margin/border in order to illustrate how they affect the content area and has nothing to do with line-height
:
span {
border-left: 1em solid red;
background: rgba(255, 0, 0, 0.2);
font-family: arial;
font-size: 25px;
}
.container>div {
margin-bottom: 5px;
border: 1px solid;
line-height: 40px;
}
.container>div:nth-of-type(1) span {
padding: 10px;
}
.container>div:nth-of-type(2) span {
border-bottom: 5px solid red;
}
.container>div:nth-of-type(3) span {
padding: 10px;
background-clip: content-box;/*I limit the background to content-box only*/
}
.container>div:nth-of-type(4) span {
margin: 20px;
}
<div class="container">
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
</div>