- From: Matthew Brealey <thelawnet@yahoo.com>
- Date: Mon, 10 Jan 2000 15:59:21 -0800
- To: www-style@w3.org
- Message-ID: <387A724E.78@yahoo.com>
Sorry I've sent this already. If so, ignore it - it was an old copy. Eric Meyer wrote: [introduction snipped] > The user agent determines which elements and > glyphs are to be in a given > line (using whatever mechanism it uses to calculate > such things). So let's > say it has an anchor, some letters, and then a > boldface element, like this: > > <A>anchor</A> some angry letters <B>boldface</B> > > In the simplest case of this example, these are all > the same font and font > size, there are no box properties set for the inline > elements, and there is > no leading due to line-height. No. There is no line-height declaration, therefore line-height: normal. Typically normal = 1.2. However, let's assume that we have ELEMENT {line-height: 1} > Thus, the line-box > is as tall as the font > used to generate the text No. The line box is as tall as font-size. Font-size, although influencing the size of rendered glpyhs does not state its absolute size. > , and will enclose the > descenders in "angry" as > well as any (hypothetical) capital letters. > Correct? No. Because of the need to place accents, etc., the tallest descender + deepest descender can > font-size. The height of the line box is entirely indepdendent of its actual content (although the number of line boxes required is), but merely by the line-height value, which in correct authoring practice is related to font-size [but even then, font-size is not the actual maximum size, but merely the value used to select a font of a given size]. This issue is outside CSS, and although it might seem bad that fonts can be larger than their font-size, it really doesn't matter - no-one uses line-height: 1 anyway. Furthermore, it is unlikely that differences will result, since even if the user and author do not have the same font, if they are of the same language, it is likely that they will overshoot their font-size by similar amounts. I can, however, see an argument for line-height: set-solid, which would use the physical maxima of the font to set line-height to such a value as to ensure that the tallest and deepst glyphs touch the bottom of their line box. This is not something I personally would use, although other people might find it useful. > Let us now introduce a change in font size for > one of the elements. > We'll set the anchor to be 200% the size of > everything else. We'll denote > this in ASCII by making it all uppercase. > > <A>ANCHOR</A> some angry letters <B>boldface</B> > > Now, how are the various pieces of the line > positioned vertically? I would > argue that they all align on their baselines, since > that's the default > value of 'vertical-align'. Correct? Yes. But vertical-align: baseline aligns with the parent box, so vertical-align: baseline in this case means text baseline = line box baseline [I think it should always mean line box baseline so <span style="vertical-align: sub">text<span style="vertical-align: baseline">text</span></span> aligns the inner span with the line box baseline, not the parent box (see my two posts on this subject from December]. > Let's add a 'line-height' value to the line. > We'll make it '12pt', > which we will assume to be the same size as the > letter and boldface text. > This means that the anchor also has a 'line-height' > of '12pt', because > 'line-height' is inherited. :linebox {font-size: 12pt; line-height: 12pt} > However, its text is > 24pt (200% * 12pt) in > size. So how tall is the line-box, really? 12 > points or 24 points? 12 points - as I said above, "The height of the line box is entirely indepdendent of its actual content". The line box does not represent a container outside which glyphs cannot go, but rather a device for alignment - each line box will be stacked one on top of another without separation, each 12 points high. When each line box is placed, the text is placed on its baseline. Perhaps the best way of picturing it is in two separate planes - 1. a 1/6inch (i.e., 12pt) line box is drawn 2. the baseline of the line box is determined [not defined at CSS 2 - but this doesn't actually matter - if a UA takes it as the bottom of the line box, all that will happen is each and every line of text will be a couple of pixels too far down, but the separation of lines will still be the same] 3. the glyphs' baselines are placed in a separate vertical plane from the line box, but perpendicular to its baseline 4. another 1/6 inch line box is drawn, its top aligned the same as the bottom of the previous one. 5. determine baseline, etc. 6. etc. This emphasises how the height of a line box is independent of the actual size of its textual content > If > the latter, how can out-sized text "bleed" out of > the line into other > lines, since line-boxes don't overlap? Indeed not - the line boxes are still 12pt, but the line box doesn't represent a barrier for text, a point made especially clear by the separate planes demonstration above. > Moving on, let's assume that the entire line is > enclosed in a SPAN. > > <SPAN><A>ANCHOR</A> some angry letters > <B>boldface</B></SPAN> > > Furthermore, let's put a border on the SPAN. Is the > border is drawn around > the outside of the text, Yes, at CSS 2. > or around the ghost box > implied by the value of > 'line-height'? I think this should be the state of affairs for CSS 3 - the rendering is ugly and illogical otherwise - if borders are allowed, so must margins be, but at CSS 2 margins can have no effect : to allow margins (logically necessary if borders are allowed, since margins are nothing more than transparent borders), they must affect the whole line box. [See my two messages in December for more on this] > Does the top border cut through the > middle of the ANCHOR, > since it's twice as tall as the 'line-height' of its > parent and itself? It must do with CSS 2; at CSS 3, it shouldn't > Does the border surround the box implied by the > 'font-size', The border must go on top of the glyph size implied by the font-size declaration. > or by the > 'line-height', This doesn't seem to work at CSS 2 - at CSS 2, borders are associated with text rather than line boxes - if the border went on top of line-height at CSS 2, borders would always overflow the line box. > or around the line-box? Ditto > Does it > change if we explicitly > assign a 'line-height' to the SPAN, or not? I don't think so at CSS 2. To return to the two vertical planes metaphor: [old stuff] 1. a 1/6inch (i.e., 12pt) line box is drawn 2. the baseline of the line box is determined [not defined at CSS 2 - but this doesn't actually matter - if a UA takes it as the bottom of the line box, all that will happen is each and every line of text will be a couple of pixels too far down, but the separation of lines will still be the same] 3. the glyphs' baselines are placed in a separate vertical plane from the line box, but perpendicular to its baseline [/old stuff] 4. borders are placed on top of the top of the position implied by font-size (i.e., fonts that have very big accents may overlap the border) This means that borders can also overflow (technically be perpendicularly above in an independent plane) the line box above or below. This is necessarily implied by CSS 2. Thus P {line-height: 18pt; font-size: 12pt}, then SPAN.insideP {border-top: 4pt} would overflow the next line box above, since the bottom edge of the border is (line-height - font-size)/2 + font-size [note no baseline calculation needed], that is to say its top edge would be (18-12)/2 + 12 + 4 = 19pt. > For even more fun, let's set the anchor to > 'vertical-align:text-top'. I proposed a minor amendment to this where text-top = line box top rather than parent box top, but this irrelevant for present purposes. I also added the necessary proviso that all text-top and text-bottoms should be aligned simultaneously, but after the performance of all other v-align, so that there isn't a loop. However, to attend to the matter at hand. It'll be easiest if I return to the planes again: [old stuff] 1. a 1/6inch (i.e., 12pt) line box is drawn 2. the baseline of the line box is determined [not defined at CSS 2 - but this doesn't actually matter - if a UA takes it as the bottom of the line box, all that will happen is each and every line of text will be a couple of pixels too far down, but the separation of lines will still be the same] [/old stuff] <new stuff - 3 is changed> 3. all vertical-align: baseline text is placed in a separate vertical plane from the line box, but perpendicular to its baseline 4. v-a: sub, super, %, length = same as baseline except move baseline up/down - trivial to implement [though I would like to see CSS changed so that these values are clipped to fit the line box rather than, as at present, them extending the line box if their top/bottom is, as a result of v-align, above/below the position implied by the line's line-height declarations] 5. vertical-align: top text is placed thus: use font-size value of text. Say font-size: 16px. Place its bottom (NB. not baseline) on (line-height - font-size). Say line-height: 20px, place its bottom 4px from the bottom of the line box. The reason for this is that you can only place the bottom of a glyph, not the top, but the idea is that the theoretical top (i.e., that implied by font-size - too slow to use max (ascent of glyphs actually used)) of the font should be at the top of the line box, thereby implying its bottom is font-size below it [again won't necessarily be actually at the line box top - dependent on the CSS-independent font characteristics] This could still result in overlap if the tallest glyph is taller than font-size 6. v-a: bottom is placed 0px from the bottom of the line box 7. v-a: text-top, the bottom of each such glyph is placed at its font-size below the top of the position of the highest (theoretical) font-size in the line box. This differs from top insofar as text-top doesn't take into account replaced elements that extend the line box height, and top uses the line box height [technically at CSS 2, it is the parent box - I want this changed to line box; but they are equivalent 99% of the time], and top therefore doesn't take into account the font-size of other elements, only line-box-height (which is max(line-height, height of replaced elements), subject at CSS 2 to extension by v-a: sub/super/length/%). Thus P {line-height: 20pt; font-size: 12pt} SPAN.insideP {font-size: 22pt} SPAN.insideP2 {font-size: 14pt; vertical-align: text-top} means that the bottom of all the text is 1pt below the bottom of the line box (common bottom, used to find common baseline of a line, = (line-box-height - max-font-size)/2 above the bottom of the line box, so common bottom = (20-22)/2 = -1pt - 1pt below the bottom of the line box. As a result, SPAN.insideP's theoretical top is 21pt (22-1) above the bottom of the line box. We use this to find SPAN.insideP2's theoretical top, which is the text-top. This implies that SPAN.insideP2's theoretical bottom (i.e., assuming no glyphs are bigger than font-size; note the theoretical bottom cannot be directly used, it is only a step towards finding the baseline, which should be calculated for top, text-top, text-bottom and bottom (the other v-a values relate to the common baseline, which is based on the whole line box) based on the element's font-size (line-height is no relevant)) is 14pt below the top of SPAN.inside, therefore 7pt above the bottom of the line box. </new stuff> > Now how is the line laid out? Where is the SPAN's > border drawn? We have :inlinebox {line-height: 12pt; font-size: 12pt} A {font-size: 24pt; /* line-height: 12pt - inherited value */ vertical-align: text-top} SPAN {border-top: solid thin; /* line-height: 12pt - inherited value */} <span><a></a></span> What happens is: common bottom is (12-24)/2 = -6pt below bottom of the orginal line box (i.e., that implied by max(line-height, height)). The v-a: baseline text is done first, and SPAN's theoretical top is therefore 12+(-6) = 6pt above the bottom of the line box. Since the large A is aligned with this, its theoretical top is 6pt above the bottom of the line box, thus meaning its theoretical bottom is 18pt below the bottom (6-24 (font-size)) of the line box. The height of the line box is from the top of the top text box to the bottom of the bottom text box. This does not mean the top of the text to the bottom - to find the top of the top text box, one must use line-height for each piece of inline content. Thus the bottom of the SPAN's text is 6pt below the bottom of the original (provisional) line box. Its text box (that is its 'mini line box') is still on the bottom of the orginal line box. However, the A is aligned with its top. Since the vertical-align is text-top, the top of its text box (whose height is 12pt) is aligned with the top of the theoretical top of the SPAN text - 6pt above the bottom of the line box. Since this is so, the bottom of its text box (it is 12pt high) is thus 6pt below the provisional line box. Therefore the height of the line box is 18pt - from 6pt below to 12pt above. Below the bottom of the line box there will be the bottom 12pt of the A element (since it is 24pt high and is placed 6pt above the top of the original, 12 above the final line box). This would be the same regardless of whether, as now, t-top refers to the parent box or to the line box, since t-top is performed after bottom [Note an omisssion, common baseline calculations _do_ take into account differently v-aligned text]. SPAN's border is placed on top of the theoretical top of the SPAN text (independently of its text box) at CSS 2. And, with: :inlinebox {line-height: 12pt; font-size: 12pt} A {font-size: 24pt /* inherited line-height: 12pt */} SPAN {vertical-align: text-top; border-top: thin solid; /* inherited line-height: 12pt */} First up, a provisional line box of 12pt is implied. Therefore, the common bottom is 6pt below the bottom of this provisional box. The A is thus (-6pt+24)-l-height above the bottom of the line box = 18pt. Since SPAN is aligned text-top, the theoretical top of the font is therefore placed at 18pt, and thus its bottom is 6pt above the bottom of the line box. Its text box (not the best term, since text isn't necessarily placed within it) is aligned with the theoretical top of the SPAN, and therefore from the top of the bottom text box to the top of the top text box is 0pt up to 18pt (the top of the SPAN's box), and thus the line box is 18pt high. The bottom 6pt of A is thus below the bottom of the line box As to the border, that is placed on top of the theoretical top of the element with which it is associated (although I belive it should be on top of the line box - see previous posts), and therefore it is placed 18pt above the line box bottom. Note that it is important that borders have no effect on line box height at CSS 2, and therefore are in a separate plane. > Now replace the anchor with an image which is > 24pt tall, but is still > text-top aligned: > > <SPAN><IMG> some angry letters > <B>boldface</B></SPAN> > > Once more: how is the line positioned vertically, > and where is the SPAN's > border drawn? The line box height is increased to 24pt by the replaced element. The SPAN's border goes on top of the theoretical top of the SPAN. That is the SPAN excluding the IMG, since border is not inherited. The v-align: text-top on the IMG places its top at the top of the SPAN text (12pt above the bottom of the provisional line box). Since its box is 24pt high, the height of the line box is 24pt (since it is 24 pt high, its top is 12pt above the top of the line box). However, this is different from if IMG had had v-align: baseline, since then there would be 6pt above and below the top of the SPAN, rather than as in the previous example, where the 12pt was all below (not literally below - separate planes; it is just that is the appearance that would be given) the bottom the bottom of the SPAN. > How does it change when the image is > set back to > 'vertical-align:baseline'? > How is this affected by > setting 'margin:1pt' on > the image? By setting 'margin:-4pt'? The vertical margins have no effect, an illogical absurdity that should be changed. > We're still not done, either. Take the following > styles, markup, and > rendering sketch: > > P {line-height: 14pt; font-size: 12pt;} > BIG {font-size: 300%;} > > <P>This is a paragraph which<BR>contains a > <BIG>BiG</BIG> element<BR> > that will do weird stuff.</P> > > This is a paragraph which > contains a BiG element > that will do weird stuff. > > Okay. The "BiG" text is on the middle line. Its > line-height, along with > everything else, is '14pt'. How much space will > there be between the > baselines of the three lines? Always 14pt - the only thing that can change this is v-align overflowing it, although I think this is absurd. > How much vertical > distance will there be > between the baseline of the "BiG" text and the other > text on its line, if > any? None, lines share a common baseline. > Now alter the above example to use these styles: > > P {line-height: 1.2; font-size: 12pt;} > BIG {font-size: 300%;} > > Again, what are the baseline separations, both > between and within lines? BIG's line box is 36*1.2 = 43.2pt, the others are 14.4pt. There is thus 1.2+36+3.6=40.8 pt between the lines > Once more, with feeling: > > P {line-height: 1.2; font-size: 12pt;} > BIG {font-size: 300%; vertical-align: middle;} > Effectively P {font-size: 12pt; line-height: 14.4pt} BIG {font-size: 36pt; line-height: 43.2pt; vertical-align: middle;} Initially a 43.2pt line box is produced (max(line-height)). V-a: middle aligns its middle with the middle of the line box plus half the x-height of the parent box. Therefore the middle of BIG's box is aligned with the point 21.6 + (half-x-height) - say 25pt. As a result, the top of the line box is 25 + 1/2*43.2 = 46.6pt above the pottom, and thus it is 46.6 pt high. > Again, what are the baseline separations, both > between and within lines? > To go back a few steps and mix things up a bit: > > P {line-height: 18pt; font-size: 12pt;} > BIG {font-size: 300%;} > > Again, what are the baseline separations, both > between and within lines? 18pt - font-size does not affect l-height. > If I were to add a SPAN to the markup in the last > few examples, and then > put a border on it so that the second line had a top > and bottom border, > where would it be drawn? Around the font, the > 'line-height', or the > line-box? > > ============================================================================ > > In summary, at least these questions need a > definitive answer: > > * What constitutes a line-box? A device for alignment purposes. > * Is the basic unit of a line-box the individual > character glyphs and > replaced elements, or the inline elements (anonymous > or otherwise, replaced > or otherwise)? No, the height of the line box does not directly relate to its text content, but only to line-height and height . > * How are the edges of the line-box affected by > content? They are not - only to height, line-height, and vertical-align - never to font-size - even with v-align, it is the overflow of the box as dictated by line-height that causes the alignment. > by line-height (leading)? > by replaced elements? If they would overflow the line box, they increase it in size. > * Where are the (half-)leading spaces placed? with > regard to what? They are a bit misleading really - essentially, half the leading goes above the theoretical top, and half below the theoretical bottom. > * What is within the line-box, and what is without? Some, but not necessarily all, of the content. Circumstances under which overflow can occur at line-height >= 1: 1. Borders 2. Fonts whose glyphs are larger than font-size; 3. At CSS 2, that's it With line-height <1, content may go outside the line box even without glyphs bigger than font-size. > * Where does the border get drawn around inline > elements? On top of the theoretical top, i.e., the top as suggested by font-size. But should be changed. > * What does font-size have to do with all of this? Nothing. > * How is outsized text positioned with regard to the > baseline? to the line-box? I.e., l-h < 1 for that text. Its bottom is placed [simplified equation] (l-h - f-s)/2, which will be below the bottom of the line box. However, if outsised text is on a line with smaller text, all share a baseline (subject to v-a: baseline), so they will all be below the bottom of the line box - this means the small text will also overlap if the line below has no big text to affect it. > * How does vertical-align affect the line-box, if at > all? At CSS 2 each element has its own box. The line box is from the top of the highest to the bottom of the lowest - affected by v-align. > * In what order is all of this done, in order to > correctly construct an > element containing line-boxes? See above. > * Are there any differences between CSS1 and CSS2 > when it comes to all this? CSS 1 was vaguer > * Are there other things I didn't think to ask > about, but are important to > understanding the inline box model? Finally as the last word on provisional line box height (used unless v-a is different) provisional_line_box_height=((max(line-height, height))>=((max-height) + max_descent)))?max(line-height, height):max(line-height, height) + max-descent) This pseudo-code takes into account the fact that max(line-height, height) is not satisfactory given P {font: 12px/12px whatever} IMG {height: 12px}, where the text and IMG must be aligned along their baseline. Since they are being aligned along their baselines, they are being placed Npx above the bottom of the line box. As a result, IMG will spill out of the top, since the line box height is 12px. Therefore, although it would be inappropriate to add max-descent in general to line box height as it would over-inflate line box heights, as in the pseudo-code, where the replaced element would otherwise overflow, it is factored in. The common_baseline is max_descent above the bottom of the common_bottom (the bottom of the provisonal line box, although the provisonal line box may move due to v-align).
Received on Monday, 10 January 2000 10:58:42 UTC