- From: Matthew Brealey <thelawnet@yahoo.com>
- Date: Mon, 6 Dec 1999 06:45:25 -0800 (PST)
- To: www-style <www-style@w3.org>
1. One area of the existing specification that I believe is poorly described is that of the vertical box model properties on inline elements. Although margin-left, margin-right, etc., are obvious, vertical margins are less so. For example, the picture http://www.w3.org/TR/REC-CSS2/images/inline-layout.gif doesn't seem to be right, since the text isn't centred in the line box, the border goes outside of the line box, margin-left and margin-right only are applied, even though the property used is margin, which sets all four margins, and padding-left and padding-right only are applied, even though the property used is padding, which sets all four sides. I would say that to resolve the difficulties (and believe me, there are difficulties), the direct consequence of which has been buggy support in browsers, relating to vertical box model properties, the margin-top simply adjusts the height of the top line box, and margin-bottom the bottom line-box, and border-top and border-bottom adjust the height of the line box in the same way, but only apply the border around the element. Conversely, horizontal box model properties (e.g., border-left) are placed normally within the box. E.g., <p style="font: 12pt/14pt sans-serif; background: blue; color: black> <pseudo title="element signifying that the enclosed text represents one line"> This is <span style="line-height: 18pt">line 1</span> </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is <span style="margin-top: 5pt;">line 2</span> </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is <span style="margin-top: 5pt; background: red">line 3 </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is</span> line 4 </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is <span style="border: 5pt solid">line 5 </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is</span> line 6 </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is <span style="border: 5pt solid; margin: 2pt; padding: 10pt; background: red">line 7 </pseudo> <pseudo title="element signifying that the enclosed text represents one line"> This is</span> line 8 </pseudo> </p> In this example, line box 1 would be 18pt high, line box 2 would be 14pt high, but would appear to the naked eye to be 19pt high. In actual fact, it would be also be 14pt high, but the 5pt would be applied to the whole line box. Line boxes 3 and 4 would also be 14pt high, but line boxes 3 and 4 would both have 5pt margin-tops (this is because if you just apply the 5pt to the inline element, either the line box above would be overlapped or the content would be obscured, or something equal undesirable). Obviously, the red background would only be applied to the content. Line boxes 5 and 6 would have 14pt high, but 5pt of space would be added above and below them, and the border would be drawn as normal around the content. As a result, the distance between the top of the border and the top of the inline box would be the same as what the distance would be between the top of text and the top of the line box if the border wasn't there. Line boxes 5 and 6 would not have a height of 14pt and a border-top 5pt - the border should be placed next to the top of the text, not next to the top of the line box. Line boxes 7 and 8 would be 14pt + 10pt above + 10pt below = 34pt high (i.e., padding is applied to increase line-height), and there would be 5pt + 2pt = 7pt above and 7pt below the line box. As a result, the line box's 'effective height' would be 48pt. The border would be applied above the content, in the 5pt of space above the top and below the bottom of the line box (height 34pt). All 48pt of effective height on both lines would be blue, with the exception of the 34pt around the SPAN box, which would be red, and the border, which would be black (since border-color's initial value is color's value = black). This would make Opera's approach, whereby large borders increase the line box height, but the borders run into each other, wrong. <q cite="http://www.w3.org/TR/REC-CSS2/visuren.html"> Line boxes are stacked with no vertical separation and they never overlap. </q> I would say not, e.g., because of margins 2. HEADING: Positioning of text within line boxes [apologies if this overlaps with the previous thread, but it was getting a bit unwieldy] To consider it logically: line-height: whatever is the one thing that we have a fixed definition for. Therefore, all we need to do is draw the line box, and once we have done that place the text within it. I believe that we should be taking a line-box-oriented approach, since given font-size: 18px, line-height: 1, the line box is 18px high, which is easily done. Now that we have a line box, whose height is fixed, we can use this as a foundation to place the text within it. To do this, we work out where the baseline should be relative to the bottom of the line box, and place the text on this. Although some fonts will have glyphs that are larger than their font-size, it is not our role to consider this - this is for the font vendors to consider. However, there are some things that it is within our grasp to decide. The main criteria are: 1. that the text appears centred within the line box 2. that the chance of overlapping at 'set solid' text (i.e., font-size: 1/1em/100%) is minimised 3. that the baseline HAS to be a constant distance above the bottom of the line box for a given vertical-align, regardless of font-size Therefore: Proposal A: should the baseline be line-height/2 above the bottom of the line box? I would say not, since the text should appear to be centred in the box, but with this proposal, it is not done so (since the baseline is centred, whereas we actually want the middle of the text to be centred). Conclusion: REJECT Proposal B: Possibly the baseline could be aligned with line-height/2 - x-height, since would have the advantage of favouring a position nearer the bottom of the line box (look at 'x' and then look at 'l'), which seems to be better than one too far up. However, this will result in glyphs that are larger than x-height overflowing [2] the line box. Conclusion: REJECT Proposal C: Apply (line-box-height - font-size)/2 as the distance between the bottom of the line box and the baseline. This is the option that Opera adopts (try <p style="line-height: 1; background: red /* must be different from rest of document */> Something quirky. </p> Since the baseline is at the bottom of the line box (since l = 1*f, and (f -f) /2 = 0, the descenders are not covered by the background (well some of them are due to internal leading [3]). This is clearly unsatisfactory - there is too much space on top of the font, and not enough underneath it, so: Conclusion: REJECT Proposal D: An equation that seems initially attractive is: bottom of line box to baseline = (linebox-height - max-x-height-in-that-line-box)/2 + (max-descent-in-that-line-box), where x-height and descent represent the actual values for the font's calculated value for font-size, rather than those native to the font. This equation satisifes the biggest concern, namely that the bottom of the text does not go outside the bottom of the line box. For example, given a line box whose max-x-height was 7pt, whose max-descent was 3pt, and whose linebox-height was 15pt, the baseline would be placed (15pt - 7pt)/2 + 3pt = 7pt from the bottom of the line box. However, if ascent > 8pt, as it is likely to be, the font will overflow the line box, so: Conclusion: REJECT Proposal E: Given instead: bottom of line box to baseline = (linebox-height - max-font-size-in-that-line-box)/2 + (max-descent-in-that-line-box) For example, given a line box whose font-size was 15pt, whose max-descent was 3pt, and whose linebox-height was 15pt, the baseline would be placed (15pt - 15pt)/2 + 3pt = 3pt from the bottom of the line box. Refined somewhat, this seems the best equation: bottom of line box to baseline = (max-line-height-in-line-box (NB, not line-box-height, since this might be increased by inline replaced elements) - max-font-size-in-that-line-box)/2 + (max-descent-in-that-line-box), since this can never result in normal glyphs overflowing their line box. e.g., given P {line-height: 1; font-size: 12pt} SPAN.inlinetoP {font-size: 24pt}, h = 24pt, f = 24pt, _if_ (i.e., this is only true if the font is one that doesn't create glyphs that are larger than the requested font-size) f >= a + d, glyphs can only overflow their line box if bottom of line box to baseline + a > f ( i.e., a + d), so (h - f)/2 + a + d > a + d, i.e., since h = f at line-height: 1em (i.e., at the minimum size you'd expect not to overlap), so (f - f)/2 + a + d > a + d, i.e., 0 > 0, which is never true, so this equation never results in overlaps for unaccented glyphs, and never for accented glyphs either if you re-define ascent as maximum accented height. This caters perfectly for vertical-align: sub, super and percentages as well [Incidentally, the spec needs to state (to avoid the absurdity of browsers (Opera, at least) increasing line-height to cater for vertical-align): <blockquote> UAs should apply vertical-align: sub as vertical-align: -nn%, where nn% is a UA-determined percentage. UAs should apply vertical-align: super as vertical-align: nn%, where nn% is a UA-determined percentage that should be the same as that used for sub. When a percentage specified is greater than that which can be fitted in the line box, the UA should clip it to a value that can. For example, given line-box-height: 1.2em; vertical-align: 15%, the vertical-align should be clipped to 10%, since there is only 10% of space that the text can be moved within the line box. Equally for sub and super - if a UA normally applies 10%, but there is only room for 5%, 5% is what it should apply. </blockquote> Thus also needed is : if calculated value for vertical-align > 0 { if ( ( (max-line-height-in-line-box - current-font-size)/2 + (calculated value for vertical-align) ) > (font-size - curent-descent) [= ascent] ) { calculated value for vertical-align = (max-line-height-in-line-box - current-font-size)/2 } } and: if calculated value for vertical-align < 0 { if ( ( (max-line-height-in-line-box - current-font-size)/2 + calculated-value-for-vertical-align [i.e., + -whatever = -whatever] + current-descent < current-descent ) ) { calculated value for vertical-align = -((max-line-height-in-line-box - current-font-size)/2) } } i.e., if calculated value for vertical-align < 0 { if ( ( (max-line-height-in-line-box - current-font-size)/2 + calculated-value-for-vertical-align < 0 ) ) { calculated value for vertical-align = -((max-line-height-in-line-box - current-font-size)/2) } } ] , since given, e.g., line-height: 20px, font-size: 14px, and descent = d, then bottom of line box to baseline = (20px - 14px)/2 + (max-descent-in-that-line-box) + .1*20 (assuming 10% as the value for %), = 3.5px + d + 2 = 5.5pt, which will fit in the line box perfectly. Here's the equation with vertical-align included: bottom of line box to baseline = (max-line-height-in-line-box - max-font-size-in-that-line-box)/2 + (max-descent-in-that-line-box) + calculated-value-for-vertical-align By adopting this baseline approach, all the problems are solved, since all we need to do is draw a box, calculate the distance to the baseline, and place the glyphs on the baseline - we don't need to bother with any of the font's characteristics except for descent, and the quoted value for font-size - if a glyph is placed on the baseline and it overlaps because it has many accents, so be it. In addition, vertical-align is easier to implement following this approach. Footnotes: 1. This approach would not be appropriate for all alphabets. 2. Overflow - not overlap. 3. Not relevant, all we need to do is calculate the size of the line box, and place the text of the requested size on the baseline - internal leading is not our concern. ===== ---------------------------------------------------------- From Matthew Brealey (http://members.tripod.co.uk/lawnet (for law)or http://members.tripod.co.uk/lawnet/WEBFRAME.HTM (for CSS)) __________________________________________________ Do You Yahoo!? Thousands of Stores. Millions of Products. All in one place. Yahoo! Shopping: http://shopping.yahoo.com
Received on Monday, 6 December 1999 09:45:27 UTC