- From: Matthew Brealey <thelawnet@yahoo.com>
- Date: Thu, 27 Jan 2000 05:10:50 -0800 (PST)
- To: www-style <www-style@w3.org>
<blockquote cite="http://www.w3.org/TR/REC-CSS2/generate.html#scope"> 12.5.1 Nested counters and scope Counters are "self-nesting", in the sense that re-using a counter in a child element automatically creates a new instance of the counter. This is important for situations like lists in HTML, where elements can be nested inside themselves to arbitrary depth. It would be impossible to define uniquely named counters for each level. Thus, the following suffices to number nested list items. The result is very similar to that of setting 'display:list-item' and 'list-style: inside' on the LI element: OL { counter-reset: item } LI { display: block } LI:before { content: counter(item) ". "; counter-increment: item } </blockquote> The result is not so very similar - UAs that render 1., 2., etc., on list-style: decimal are wrong. <blockquote> The self-nesting is based on the principle that every element that has a 'counter-reset' for a counter X, creates a fresh counter X, the scope of which is the element, its preceding siblings, and all the descendants of the element and its preceding siblings. In the example above, an OL will create a counter, and all children of the OL will refer to that counter. </blockquote> This is wrong/ill-thought-out. If one defines self-nesting in these terms, display: list-item is broken. For example: LIST {display: list-item} <LIST> Some LIST text that should be numbered 1. <LIST> Some LIST text that should be numbered 1. </LIST> <LIST> Some LIST text that should be numbered 2. </LIST> <LIST> Some LIST text that should be numbered 3. </LIST> </LIST> <LIST> Some LIST text that should be numbered 2. </LIST> Clearly the result I describe here is correct, for otherwise nested list items cannot be specified using display: list-item (as the definition stands, it is not possible to describe the behaviour of LI elements using display: list-item (ironic don't you think?), since nesting of list items requires a counter-reset on the OL element: <q> The self-nesting is based on the principle that every element that has a 'counter-reset' for a counter X, creates a fresh counter X, </q> Now in order to implement this for UL/OL and LI, it is necessary to have OL, UL {counter-reset: functionname}, but LI {display: list-item} doesn't create a counter function to which we can refer, so there is nothing that we can reset. The consequence of all this is that if one were to specify display: list-item on LI, it would serve to suppress the nesting (because the counter resets won't work) and thereby wreck LI ). In order to define self-nesting in terms that work without requiring an OL/UL-type element to reset the counter value (and therefore requiring a LI-type element to use proper counter functions so that OL and UL have something to reset), I would suggest the following definition. <suggestion> The self-nesting is based on the principle that direct or indirect (an indirect descendant is one such as: <LI> Indirect ancestor </LI> <OL> <LI> Indirect descendant </LI> </OL> ) descendant elements that refer to the same counter function, create a fresh counter X, the scope of which is the descendant element and its siblings. In the example above, an OL will create a counter, and all children of the OL will refer to that </suggestion> This can in no way be considered satisfactory, since it restricts counter functions to use by siblings, so the alternative is to withdraw display: list-item and force people to use counter functions, which are much more useful and flexible. <blockquote> If we denote by item[n] the nth instance of the "item" counter, and by "(" and ")" the beginning and end of a scope, then the following HTML fragment will use the indicated counters. (We assume the style sheet as given in the example above). <OL> <!-- (set item[0] to 0 --> <LI>item <!-- increment item[0] (= 1) --> <LI>item <!-- increment item[0] (= 2) --> <OL> <!-- (set item[1] to 0 --> <LI>item <!-- increment item[1] (= 1) --> <LI>item <!-- increment item[1] (= 2) --> <LI>item <!-- increment item[1] (= 3) --> <OL> <!-- (set item[2] to 0 --> <LI>item <!-- increment item[2] (= 1) --> </OL> <!-- ) --> <OL> <!-- (set item[3] to 0 --> <LI> <!-- increment item[3] (= 1) --> </OL> <!-- ) --> <LI>item <!-- increment item[1] (= 4) --> </OL> <!-- ) --> <LI>item <!-- increment item[0] (= 3) --> <LI>item <!-- increment item[0] (= 4) --> </OL> <!-- ) --> <OL> <!-- (reset item[4] to 0 --> <LI>item <!-- increment item[4] (= 1) --> <LI>item <!-- increment item[4] (= 2) --> </OL> <!-- ) --> </blockquote> Finally, another alternative might be simply to point out that LI's behaviour cannot be specified using display: list-item alone, and simply to give a definition of display: list-item (the current spec fails miserably (see Mozilla's treatment of it with list-style: decimal to see the problems this has caused) to give any definition of what display: list-item does in terms of counter values). However, this causes serious problems in that since list-style-* only affects elements with display: list-item, and not those with display: marker, this means that these properties, which are only of any use on LI, have no effect on any element whatsoever (because LI is not defined by display: list-item). Conclusion: There are two options: 1. change the self-nesting rules so that list items can be described without resort to counter-resets, but restrict the flexibility of counter functions to sharing only between sibling elements, or 2. leave display: list-item and the list-style-* properties as entirely useless - NOT AN OPTION. Since it is clear that the first option is the only real path to take, it might be beneficial to see if it could be refined somewhat. I've just considered it, and I think I've come up with quite a good suggestion - simply use my self-nesting rules for display: list-item and the existing ones for other generated content. Until such time as these changes gain adoption, I'm wondering what the display: list-item property actually does, because I know for sure that it doesn't specify LI - for example: <address> This should have a list item numbered 1. </address> <address> This should have a list item numbered 2. </address> with ADDRESS {display: list-item} results in a number 0 on both in Mozilla. Presumably the current meaning is that each selector sets up a counter function that is displayed and incremented, but what about: .class {display: list-item} #id {display: list-item} <p class="class"> Number 1 <p id="id" class="class"> Number ?. <p class="class"> Number ? <p id="id"> Number ? If one assumes that .class sets up a counter function, is it simply enough to say that the id/class P only increments the id function because to increment several functions one must specify .class {counter-increment: function1 function2}, or is it false to try and treat each display: list-item element as a counter function equivalent. PS Does text-decoration affect marker boxes? ===== ---------------------------------------------------------- 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!? Talk to your friends online with Yahoo! Messenger. http://im.yahoo.com
Received on Thursday, 27 January 2000 08:10:52 UTC