Re: [css3-values] use cases and the design of 'cycle()'

On Mon, Apr 9, 2012 at 11:11 AM, Kang-Hao (Kenny) Lu
<kennyluck@csail.mit.edu> wrote:
> While reviewing CSS3 V&U, I realized that 'cycle()' doesn't really solve
> a use case I thought it would solve.
>
> Use Case A: In a User Interface built by nesting elements (say,
> <table>), set background color on the elements alternatively along the
> nesting level. See picture[1]
>
>  table {
>    background-color: cycle(gray, white);
>  }
>
> doesn't work with the current definition of 'cycle()':
>
>  # The value returned by ‘cycle()’ must be determined by comparing
>  # the inherited value I (the computed value on the parent, or, for
>  # the root, the initial value) to the computed values Cn returned by
>  # the n-th argument to ‘cycle()’. For the earliest Cn such that
>  # Cn = I, the value returned by cycle is Cn+1. However, if this Cn is
>  # the last value, or if there are no Cn that equal I, the computed
>  # value of the first value is returned instead.
>
> because 'I' is always 'none'.

?  Why is I always 'none' here?  Tables are allowed to have
background-colors.  Also, 'none' isn't even a valid value for
background-color.

Your example should work.  Of course, 'background-color' isn't
inherited by default, so if you want it to pierce through <tr> and
<td> to get to a nested <table>, you'll have to set "tr, td {
background-color: inherit; }" as well.


> I would guess that my use case is more common than
>
> Use Case B (example 16): make an element italic, but make it normal if
> it's inside something that's italic.
>
> though I can't quite prove it. Perhaps Use Case A is really not very
> common. In any case, I believe they are both certainly more common than
>
> Use Case C (example 17): cycle between markers for nested lists
>
> because I doubt anyone would really use <ul> more than three levels, but
> I am happy to be proved wrong with links to examples.
>
>
>
> So, is my use case important to change the current definition of
> 'cycle()'? If yes, I have two proposals:
>
> Proposal A: For non-inheritable properties, define the inherited value I
> as the nearest non-initial computed value of an ancestor element. Make
> no change to the inherited value I for inheritable properties.
>
> Proposal B: 'cycle()' works as if there's an anonymous counter for each
> declaration with a 'cycle()', which is incremented when entering
> elements where that declaration applies and wins and decremented when
> leaving such elements. 'cycle()' returns the value corresponding to the
> value of the counter. (Some details about what 'a declaration' is
> missing for the moment.)

Your proposal B requires us to either attach meaning to the *source*
of a declaration (such that splitting "A,B{...}" into "A{...} B{...}"
or merging in the opposite direction will change the behavior of the
CSS by creating more/less counters) which has no precedent in CSS and
is almost certainly a bad idea, or requires us to compare cycle()
declarations to see if they're identical (and thus should use the same
counter) which also relies on value-equality, which you list as a
problem.

It also works incorrectly if you have a chain of cycle()s that work
together, but in the middle you instead set the value to an explicit
option - the following cycle() will just ignore that value and
continue to iterate to the entry following whatever the grandparent
used.

The current definition was developed specifically to avoid problems
like the above.


> I prefer Proposal B, and here some advantages and disadvantages:
>
> == Advantages ==
>
> 1. It is a lot more intuitive and less error-prone by specifying "use x,
> and then y, and then z..." than "use x if the parent is y...". For
> example, css3-lists has
>
>  # /* Default list style types for unordered lists up to 3 deep */
>  # ul { list-style-type: disc; }
>  # ul ul { list-style-type: square; }
>  # ul ul ul { list-style-type: circle; }
>  # /* Alternately, if Values & Units Level 3 is supported, replace
>  #    the above three lines with: */
>  # ul { list-style-type: cycle(disc, square, circle); }
>
> in the "Sample style sheet for HTML", which doesn't work without
> Proposal B applied because the inherited value I is 'disc' from the
> initial value (and people forget that) and so the 'list-style-type' of
> the top level <ul> is 'square'.

Ah, yes, that's definitely an error.  This aspect is a bit of a
footgun, but it should be quickly obvious in practice.  I'll fix the
error.


> 2. Duplicate values in a 'cycle()' work as expected, which is more
> natural, I believe.

The fact that duplicate values don't currently work is slightly sad, I
agree.  I don't know how to fix it without introducing problems like
what I outline above.

~TJ

Received on Monday, 9 April 2012 19:06:29 UTC