This is a proposal for clearer explanation, clarification, and modification of the CSS2 inline box model. It is more than just an explanation of CSS2's model, since it incorporates a number of changes that I have proposed.
This document is badly in need of some illustrated examples. Hopefully I'll make some soon.
This document makes no attempt (yet) to cover the formatting of marker boxes or compact elements or deal with bidirectionality.
There are two types of inline elements: replaced inline elements and non-replaced inline elements. In general, non-replaced elements are those whose content is contained in the document, whereas replaced-elements are those whose content is outside of the document. For example, in the code:
Visit the <a href="http://www.w3.org/">World Wide Web Consortium</a> to learn about...
the content of the
a element is "World Wide Web Consortium".
Replaced elements are those where the content comes from some external
source, for example, an
However, as far as the inline box model is concerned, the definitions
are as described above except that elements with display
latter is a proposed type for CSS3 to accommodate form elements) are
considered replaced elements.
The box properties (margin, padding, and border properties) on inline
replaced elements are handled just like box properties on block-level
elements. The content height and width are determined by the
width properties (which may be
auto), and the padding, border, and margin are placed outside of
the content. For inline replaced elements, the only
edge relevant to the inline box model is the margin edge (the outside
edge of the margin).
Inline non-replaced elements are treated quite differently.
The content width of an inline non-replaced element is the
width required by its content (which is affected by the
font properties and also
letter-spacing, which in turn are affected by whether
justify or not). The
width property has no effect. The horizontal margin,
border, and padding are placed to the left of the beginning of the
inline element and to the right of the end, but have no effect at
Heights of inline elements are more complicated. For the purposes of the box properties, the font height is used. The vertical padding and border are placed outside the font edge. If the inline element is broken over lines, they occur on every line. However, they have no effect on the layout of the inline elements. (Since the vertical box properties have no effect on the layout of the elements, the vertical margin properties have no effect at all.) The logical height of an inline element will be discussed later.
Block level elements (in which I include elements of display
and some elements of display
run-in) can contain three types of content. They
can contain other block-level elements, inline elements, or
text. In terms of the DOM, the first two types of
Element Nodes and the latter type are
Text Nodes. Whenever a block-level element
contains inline elements or text, all consecutive inline
elements and text nodes not separated by block-level elements
are enclosed within one anonymous inline box. (This
box is later split during the construction of lines. [NOTE: Would it be clearer to call the two types
of anonymous inline boxes two different things?]) In
other words, anonymous inline boxes are created according to the
Anonymous inline boxes are considered to have the
line-height properties of
their parent block-level element.
line-height property specifies the logical
height of an inline element. This is the height used in the
vertical alignment of inline elements and the construction of
line boxes. [NOTE: Should it instead be said that
font-size) is the
leading? This makes a difference when multiple fonts are mixed
because the first font does not have sufficient characters. I
think it would be far superior since it would prevent potential
overlap or narrowing of spaces between lines because of one or
two glyphs. But is it too complex?]
line-height property takes four types of values (other than
<number>, and <percentage>, as described
in CSS2. <length> and <percentage> values have
computed values that are lengths, and therefore the computed
values inherit as lengths. Therefore, they are dangerous on any
element whose descendants have a different font size. <number>
normal values have computed values that are scaling
factors, and therefore inherit as scaling factors that are multiplied
by the font-size when used in calculations. They are therefore safe.
normal be considered
to be a computed value so that it can vary by font, using information
provided in the font metrics?]
[NOTE: Should percentages and scaling factors
be based on the computed font size, the actual font size (of the
first font in the font set?), or the
actual max-ascent to max-descent (of the first...?)?]
There are five important horizontal lines in the box generated by a non-replaced inline element: the logical top, the font top, the baseline, the font bottom, and the logical bottom. This section explains how to compute the relative positions of these five lines. The distance from the font top to the font bottom (i.e., between the font edges) is called the font height, and the distance from the logical top to the logical bottom (i.e., between the logical edges) is called the logical height. (The logical height is given by the line-height property.)
Many non-replaced inline elements contain text. In some cases that text is a child of the inline element itself, whereas in others, the text is contained within other descendant inline boxes. (In a DOM sense, the former case is when the text nodes are children of the inline box and the latter is when the text nodes are descendants but not children.) When the inline element has text nodes as children, the metrics of all the fonts used to set the child text nodes determine the font height and font edges of the inline box. (Note that multiple fonts are only used when the first font in the font set does not contain all the glyphs needed.) When the inline element does not have text nodes as children, the metrics of the first font in the font set (i.e., the first font that would be tested for the presence of a character) are used instead.
The metrics of every font specify a baseline, a max-ascent (largest distance a character extends above the baseline), and a max-descent (largest distance a character extends below the baseline). [NOTE: Are the latter two the correct terms?] The font bottom of an inline box is below the baseline, separated from the baseline by the largest max-descent of the relevant fonts. (The relevant fonts, as noted above, are either those actually used or the first font in the font set.) The font top of an inline box is above the baseline, separated from the baseline by the largest max-ascent of the relevant fonts. [NOTE: Note that some people (a minority), myself included, believe that the distance between the max-ascent and max-descent for any given font should be the font-size that font claims. However, many scalable fonts do not behave this way.]
The difference between the logical height and the font height is called the leading. (The leading is negative when the font height is larger than the logical height.) This leading is distributed equally on both sides of the font height. That is, the logical top and the logical bottom are placed so that the midpoint (midline?) between them is the same is the midpoint (midline?) between the font top and the font bottom. Half the leading is called the half-leading. The logical top is above the font top by a distance of the half-leading, and the logical bottom is below the font bottom by the same distance. (If the half-leading is negative, then the above/below relationships are reversed.)
Note that anonymous inline boxes are no exception to these rules. They have a baseline, and their font edges are determined by only the fonts used for the anonymous text within them (or the first font in the font set), not the text contained within inline elements that they contain. Note also that their logical height is determined by the line-height property (of the element corresponding to the parent block box) just as the logical height of inline boxes is determined by the line-height property (of the element corresponding to the box itself).
There are two types of values (excluding inherit) for the
vertical-align property: anchored and loose. The anchored
vertical alignment types specify a vertical-alignment for an
inline box relative to its parent inline box. The loose vertical
alignment types specify a vertical alignment within the line box. Note that the vertical alignment
of anonymous inline boxes cannot be specified by the
vertical-align property on their parent block,
vertical-align on an anonymous inline box
would be meaningless. [NOTE: It's actually
not meaningless in all cases, but only top and bottom would be
The anchored vertical-alignment types are as follows:
ex? Should this be defined in terms of an
ex?] [NOTE: Which edge is used for finding the midpoint of a replaced element?]
font-size, and then treat as a <length>. Negative percentages are allowed. [NOTE: Is the computed value or the actual value (which?) of the font-size used?]
The loose vertical-alignment types are as follows (terms used will be defined later):
[NOTE: Why isn't there a loose type for the middle of the line
box? Is that what the proprietary
The inline content (inline elements and text) within a block
level element is broken into lines using a line-breaking
algorithm. [NOTE: Should Unicode be
cited?] When doing this, the sizes of words (affected
letter-spacing), whitespace (affected by
word-spacing), replaced elements, and horizontal
margins, border, and padding must be considered. Lines are
typically broken at word-breaks, although breaks may be
permitted within words, forced, or prohibited between words.
Forced breaks include the beginning or
end of a block-level element and any markup or characters that force
The content within each line is placed within a line box. If an inline element is split between lines, then more than one inline box is used to represent that element. (Note that horizontal box properties still only apply at the beginning and end of the element.) Similarly, when an anonymous inline box is split between lines, it is split into one anonymous inline box per line. Therefore, in the "formatting tree," every line box has exactly one child, which is always an anonymous inline box. This child is called the root of the line. Note that the line box is often taller than this anonymous inline box (the root of the line).
The width of line boxes is the width of the containing block box minus any space occupied by floats. The line boxes are stacked vertically within the block box with no separation or overlap, beginning at the top inner edge of the block. If the block has a height of auto, the bottom of the last line box determines the bottom inner edge of the block box.
The horizontal alignment of the content within the line box is
controlled by the
text-align property of the
parent block-level element, which can take the following values
for block-level elements (excluding inherit):
This section is based on a post I made to www-style, but I have improved (I hope!) the terminology.
In this section I will refer to boxes generated by elements that have a loose vertical alignment as loose boxes and those generated by elements that have a fixed vertical alignment as anchored boxes. The root of the line is always a loose box. Each loose box in a line has a loose subtree of boxes. This includes the box itself and all of its descendant boxes except for those that are loose or are descendants of such a descendant loose box.
All the boxes within each loose subtree are related by fixed vertical alignments, and therefore their positions relative to each other are clearly specified. Every loose subtree has a loose subtree top, which is the highest of the logical tops of the boxes in that loose subtree, and a corresponding loose subtree bottom. The distance between them is the loose subtree height.
The height of the line box is the largest of the heights of the
loose subtrees within the line box. This tallest loose subtree
extends from the top of the line box to the bottom. If this
tallest loose subtree is the one corresponding to the root of
the line, then all the other loose subtrees are aligned
according to the value of the
property on the element generating the box that is the root of
the loose subtree. If this tallest loose subtree is not the
one corresponding to the root of the line, then the position of
the loose subtree corresponding to the root of the line is
undefined, but all the other loose subtrees are aligned (as in
the previous case) according to the relevant value of the
vertical-align properly. However, it is suggested
that the root of the line be aligned as if the relevant
vertical-align value were that of the tallest
loose subtree in the line.
I do not guarantee that these lists are complete.
line-heightproperty no longer has any direct effect on block-level elements.
vertical-alignproperty on a block-level element no longer affects anonymous inline boxes within it.
bottomvalues for vertical align as I described before, and made suggestion on handling ambiguous cases.
inline-blockshould be treated as replaced elements within the inline box model (although they have their own inline box models within them).
(Back to CSS, David Baron)
LDB, email@example.com, 2000-01-09