- From: Ian Hickson <ian@hixie.ch>
- Date: Thu, 7 Aug 2003 12:41:25 -0700 (PDT)
- To: Roger Larsson <roger.larsson@incrementa.se>
- Cc: "www-style@w3.org" <www-style@w3.org>
On Thu, 7 Aug 2003, Roger Larsson wrote: > > I would appreciate if someone would like to clarify the implications of the > "list-style-position" property. My current thinking on this is as follows. Note that I describe this in terms of the CSS3 model: http://www.w3.org/TR/css3-lists/ ...not the CSS2.1 model, because the former is much more clearly defined. (This is only my thinking. I'm the editor of the above spec, but I am not speaking for the working group here, and this could all change before we reach a stable spec. It's reasonably unlikely, however, since this is basically a description of the CSS2 model, in more detail.) Markers are created by setting an element's 'display' property to list-item. As far as rendering goes, the list-item display type is otherwise identical to the block display type. The marker box is only created if the computed value of the 'content' property for the pseudo-element is not 'inhibit'. For more details on the current thinking of how 'content' works on ::marker, see the Generated and Replaced Content draft: http://www.w3.org/TR/css3-content/ In the 'inside' positioning model, the ::marker pseudo-element is placed at the beginning of the first line box of the principal block box. This will typically cause the first character of the marker to match the element's ::first-letter pseudo-element. For the purposes of white space collapsing, the marker is considered to be on the line. Typically this will make leading white-space in the block itself significant. This is the same as for ::before and ::after pseudo-elements. The 'display' property always computes to inline on an 'inside' marker pseudo-element. The 'float' and 'position' properties do not apply. A long marker or one containing newlines preserved by the 'white-space' properties will wrap onto several lines, just like any long inline element. If the elements' 'list-style-position' property has the value outside, then the value of the element's ::marker pseudo-element's 'content' property is formatted in an independent marker box, outside the principal box. Marker boxes are formatted as an inline-block (i.e., they fit in one line box), so they are not as flexible as floats or absolutely positioned boxes. The 'display' property always computes to inline-block on an 'outside' marker pseudo-element. The 'float' and 'position' properties do not apply. Marker boxes have padding, borders and margins, just like inline-block elements. The marker box will be vertically aligned with the first line of content in the principal box, as specified by the pseudo-element's 'vertical-align' property. (The principal box is the main one generated for the element with its 'display' property set to list-item, as opposed to the marker box.) The marker box participates in the height calculations of the principal box's first line box. Thus, markers are aligned with the first line of an element's content. If no first line box exists in a principal box, the marker box establishes its line box alone, as the first box of the principal block box. (The first line of a principal box is the one matched by the box's '::first-line' pseudo-element. It might not be a direct child of the box, but it must be in flow.) The end of the marker box is horizontally aligned with where the start of a line box directly inside the list-item element would be, given the vertical position of the marker: for example in a left to right context, the right margin edge of the marker box coincides with the left edge of the line box. Thus if a float intersects the element, moving the line box start, the marker box is moved as well. It is the responsibility of the author to ensure that sufficient margins are provided on floats to prevent marker boxes overlapping with them. The CSS3 Box Model will define the properties 'float-displace' and 'indent-edge-reset' to control how far line boxes are moved in the presence of floats. Spaces at the front of the text are collapsed away according to the 'white-space' properties, as if the marker was not present. If the value of the 'width' property is auto, the marker box content width is that of the content, otherwise it is the value of 'width'. For values of 'width' less than the content width, the overflow is visible. The 'overflow' property does not apply. The 'text-align' property determines the horizontal alignment of the content in the marker box. Marker boxes may overlap principal boxes and other marker boxes. Overlap could happen for several reasons. If several nested elements without inline content all have marker boxes, for instance, or if a marker box has negative margins. Marker boxes are rendered at the same stack level as inline content of the principle box, as if it was the first box of the first line box. The CSS2 'marker-offset' property is obsoleted in this model and has no effect. (It is replaced by the 'margin-right' property in left-to-right text, and the 'margin-left' property in right-to-left text.) 9.3. Edge cases of note for 'outside' marker boxes If the marker box contents consist of just one image (as would typically be the case if 'list-style-image' is set, for example), then the marker box becomes a replaced inline-block element. In this state, the block-progression-direction (vertical in left-to-right text) margins, borders, and padding of the marker box contribute to the height of the line box. In the normal case, only the 'line-height' does. In the absence of a margin on the marker box, and in the absence of any padding on the list item's principal box, borders around the principal box would go under the marker box. (That is to say, the marker bok would overlap the borders of the list item's principal box.) Several nested list items with only one line box between them, in the inner most list item, will result in several marker boxes all taking part in the same line box model alignment calculations. Authors wanting to stop this effect, and instead generate empty line boxes for the outer marker boxes, can do so by generating a ::before pseudo-element with its 'content' property set to the empty string. Note that if a float intersects such a scenario, the markers may well end up overlapping, because it is likely that the fictional line boxes with which the ends of the markers are horizontally aligned would end up starting at the same position. For example, the following stylesheet and document fragment: item { border: solid orange; padding; 0.5em 0.5em 0.5em 3em; display: list-item; counter-increment: counter; } item::marker { content: counter(counter) '.'; margin-right: 0.5em; } float { float: left; margin-right: 2em; } <item> <item> <item> List item text. </item> </item> </item> Would render as in the first set of boxes below if there was no float present, and as in the second set if a float was present and overlapping the boxes. A list item containing a series of nested and adjacent blocks with a line box some way down will cause the marker to take part in that line box's alignment. If the DOM of the document or the stylesheet is changed dynamically, this can cause the list marker to radically change position. In the following example, the content is centered within a marker box of a fixed width. This document: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>Content alignment in the marker box</TITLE> <STYLE type="text/css"> LI::marker { content: "(" counter(counter) ")"; width: 6em; text-align: center; } LI { display: list-item; counter-increment: counter; } </STYLE> </HEAD> <BODY> <OL> <LI> This is the first item. </LI> <LI> This is the second item. </LI> <LI> This is the third item. </LI> </OL> </BODY> </HTML> should produce something like this: (1) This is the first item. (2) This is the second item. (3) This is the third item. The next example uses markers to number notes (paragraphs). The following document: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <HTML> <HEAD> <TITLE>Markers to create numbered notes4>/TITLE> <STYLE type="text/css"> P { margin-left: 12 em; } P.Note::marker { content: url("note.gif") "Note " counter(note-counter) ":"; text-align: left; width: 10em; } P.Note { display: list-item; counter-increment: note-counter; } </STYLE> </HEAD> <BODY> <P>This is the first paragraph in this document.</P> <P CLASS="Note">This is a very short document.</P> <P>This is the end.</P> </BODY> </HTML> should produce something like: This is the first paragraph in this document. Note 1: This is a very short document. This is the end. The following example illustrates how markers may be offset from their element. This HTML application and style sheet: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE>Marker example 5</TITLE> <STYLE type="text/css"> P { margin-left: 8em } /* Make space for counters */ LI::marker { margin: 0 3em 0 0; content: counter(list-item, lower-roman) "."; } LI { display: list-item } </STYLE> </HEAD> <BODY> <P> This is a long preceding paragraph ...</P> <OL> <LI> This is the first item. <LI> This is the second item. <LI> This is the third item. </OL> <P> This is a long following paragraph ...</P> </BODY> </HTML> should produce something like this: This is a long preceding paragraph ... i. This is the first item. ii. This is the second item. iii. This is the third item. This is a long following paragraph ... (Note the use of the implicit counter increment.) HTH. Let me know if you see anything wrong with this model! Cheers, -- Ian Hickson )\._.,--....,'``. fL "meow" /, _.. \ _\ ;`._ ,. http://index.hixie.ch/ `._.-(,_..'--(,_..'`-.;.'
Received on Thursday, 7 August 2003 15:39:17 UTC