This document is not intended as a simple introduction to the inline formatting model. It is instead a terse dissection of the terms and processes inherent in inline formatting, and the consequences of the rules laid out in CSS2. The learning curve here is quite steep; missing even a small point may result in fundamental misunderstanding. This document has withstood repeated scrutiny from both the CSS Working Group and the wider CSS community, but that does not mean it is either perfect or complete. There may be implications which are not presented here, and it is possible that some phrasing will be confusing to new readers. It is firmly believed that the conclusions which are presented are correct. If you believe that this document is in error, please bring your points to firstname.lastname@example.org for discussion. Thank you.
In order to clearly explain the workings of the inline formatting model, it is important to detail the terminology to be used. First, some equivalences, and then explanations of the terms used.
The following behaviors fall out of this description:
Furthermore, the inline boxes are aligned according to the value of vertical-align. This does not fall out of the description above, but is a rule introduced in CSS2:10.8.
In the case of a line which contains only inline non-replaced elements which are all the same font-size and line-height, and all of which have the same vertical alignment, the solution is simple. The content-area is defined by the font-size of the elements, and the height of the line-box is equal to the value of line-height. (This is implicit in the processes more fully explained below.)
In the case of a line which contains inline elements, both replaced and non-replaced, which have differing font-size and line-height values, the solution is as follows. For each element, the content-area's height is taken from the font-size of each non-replaced element, and from the intrinsic height of a replaced element and any padding, borders, or margins it has. The leading is then applied to each element, half above and half below. This yields a number of inline boxes which are aligned according to the value(s) of vertical-align. The highest inline box's top defines the top of the line-box, and the lowest inline box's bottom defines the bottom of the line-box.
This means that a sufficiently large element, even with a very small line-height, can increase the distance between successive baselines by altering the size of the content-area. For example, consider:
<P style="line-height: 12pt; font-size: 12pt;"> <A style="font-size: 128pt;">anchor</A> angry text <B style="vertical-align: top">bold</B> </P>
The anchor's content-area is 128pt high, but its inline box is only 12pt high thanks to line-height. This inline box is well above the baseline; for argument's sake, we'll say the bottom of the anchor's inline box is 30pt above the baseline. This puts the top of its inline box 42pt above the baseline. The anonymous text is on the baseline, with a content-area 12pt high, and its bottom is 2pt below the baseline. The bold text's content-area is also 12pt high, but it has been vertically aligned to the top of the line-box.
The line-box is now calculated to be 44pt high: 42pt above the baseline, and 2pt below it. The bold text has the top of its inline box (which is, in this case, coincident with its content-area) placed against the top of the line-box. The anonymous text has a 30pt space above it, while the anchor "bleeds" into the adjacent lines by 58pt to the top, and 26pt below the baseline. (Note that these figures are a result of the assumption that the bottom of the anchor text's inline box is 30pt above the baseline. The extent of bleeding will depend on where exactly the midpoint of the anchor's content-area rests in relation to the baseline.)
Consider this test document, and a proposed reference rendering. In both, the markup shown above is used in an expanded setting, and twice: the first time as shown, the second time with a 36pt anchor.
If a replaced element appears in the line, its content-area is equivalent to its intrinsic height and width, plus any padding, border, or margins. line-height has no effect on the inline box of replaced elements (but is used when interpreting percentage values for the vertical-align property). For example, consider:
<P style="line-height: 12pt; font-size: 12pt;"> <IMG SRC="filler.gif" style="height: 120pt; width: 16pt; margin: 8pt;"> angry text <B style="vertical-align: top">bold</B> </P>
The total height of the image's content-area is 136pt (120pt + 8pt + 8pt), and the line-height of 12pt is ignored. Furthermore, the image's bottom outer edge (content plus margins) will be aligned with the baseline, which will raise the top of the line-box, since the top of inline box of the image will be higher than was the anchor's in the previous example. The only way to make the inline box of a replaced element smaller than the size of the element is to use negative margins. The top-aligned boldface text will align its top with the top of the line-box, which also happens to be the top outer edge of the image (content plus margins).
Consider this test document; and a proposed reference rendering. The markup shown above is used in an expanded setting, and twice: the first time as shown, the second time with a 30pt image with a 6pt margin.
If a parent inline element has borders set, those borders will coincide with the font-size of the element; this should also match the element's content-area, outside of which descendant elements may "bleed." For example, consider:
<P style="line-height: 12pt; font-size: 12pt;"> <SPAN style="border: 1px solid gray;"> <A style="font-size: 72pt;">anchor</A> <IMG SRC="filler.gif" style="height: 60pt; width: 16pt; margin: 4pt;"> angry text <B style="vertical-align: top">bold</B> </SPAN> </P>
The SPAN's border will coincide with a hypothetical "default" content-area, which in this case is 12pt high, since that is the font-size inherited from the parent paragraph. (In addition, the SPAN's content-area happens to coincide with the SPAN's inline box in this case, since font-size and line-height have the same values.) This border would cut through the outsized elements within the paragraph, and could well appear below any top-aligned elements. In cases where an inline element overlaps the SPAN's inline box border, the specification does not define which overlaps which.
Consider this test document; and a proposed reference rendering. The markup shown above is used in an expanded setting, and twice: the first time as shown, the second time with a 30pt image with a 2pt margin and 36pt anchor text.
For some general cases, see this test document, and Håkon Lie's proposed reference rendering(s) of that document.
On the origin of "for argument's sake, we'll say... 30pt above the baseline":
Consider a font such as Helvetica. The baseline in Helvetica is positioned so that the descent from the baseline is -219/1000 EM and the ascent is 781/1000 EM. Therefore, for a 'font-size' of 128pt, the descent is -28pt (128pt*219/1000) and the ascent is 100pt. By the rules for 'line-height', which is 12pt in this example, the halfleading that is to be applied is (12pt-128pt)/2 = -58pt. This half leading is measured from the top and bottom of the 128pt EM. Therefore, the bottom of the content area of the inline box with the 128pt font is at -28pt-(-58pt) = 58pt-28pt = 30pts. Similarly, the top of the content area of the inline box is at 100pt-58pt = 42pt.
(Note that the ascent and descent of Helvetica have been slightly modified to make the numbers above "be nice". The actual ascent and descent of Helvetica are closer to 775/1000 EM and -225/1000 EM.)
The somewhat "strange" positioning of the content area with respect to the baseline is due to the baseline NOT being at the center of the glyph, but being biased toward the lower side of the glyph. Note that this example is given to bring home one of the aspects of the CSS definitions and not because anyone believes that one should use very large negative leading on a font.
-- Steve Zilles