W3C home > Mailing lists > Public > www-style@w3.org > January 2000

Nightmare on generated content street

From: Matthew Brealey <thelawnet@yahoo.com>
Date: Thu, 27 Jan 2000 05:10:50 -0800 (PST)
Message-ID: <20000127131050.25441.qmail@web901.mail.yahoo.com>
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 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:54:03 GMT