[css-variables] Cycling between values with variables

tl;dr: It looks like Variables can already solve the cycle() example
that Kenny brought up, where you want to cycle between properties that
don't inherit, on elements that aren't directly nested.

In an earlier css3-values thread, Kenny brought up an example where
the current cycle() function doesn't work.  Here's a variant
construction of his example:

<!DOCTYPE html>
<blogpost>
  ...
  <comments>
    <comment id='a'>
      <div class=content>
        foo bar
        <comment id='b'>
          <div class=content>
            reply
            <comment id='c'>
              <div class=content>
                reply to the reply
              </div>
              <div class=actions>...</div>
            </comment>
          </div>
          <div class=actions>...</div>
        </comment>
      </div>
      <div class=actions>...</div>
    </comment>
  </comments>
</blogpost>

You want the <comment>s to alternate between white and silver backgrounds.

If the <comment>s were directly nested inside of each other, you could use:

comment { background-color: cycle(white, silver); }

However, there's a wrapper <div> between a <comment> and its parent
<comment>.  You *might* be able to get away with setting a rule like
"div.content { background-color:inherit; }", but assume that this
isn't doable.  (Perhaps the color is partially-transparent, or maybe
we're actually cycling background-image or some other property that's
detectable when it's applied extra.)

The naive solution would look like:

comment { var-background: cycle(white, silver); background-color:
var(background); }

This is intended to shuttle the value around in the var, where it
doesn't have a visible effect, and it inherits by default.  David
Baron initially suggested this, and I supported it.

However, it doesn't work as written, because variables don't resolve
computed values like normal properties, so the cycle() never resolves.
 The <comment>s all receive "cycle(white,silver)" as their
background-color, rather than a "silver" or "white" in a cycling
fashion, and we're back to square one with all of them being white.

Shane and I discussed this, and originally came up with an idea that
would let you force variable evaluation in a particular property's
context.  However, Luke (my co-editor on the spec) came up with a much
simpler solution (simpler in terms of requiring less new spec
abilities):

comment {
  var-background: white;
  var-background2: silver;
  background-color: var(background);
}

comment comment {
  var-background: var(background2);
  var-background2: var(background);
}

This obviously extends to an n-cycle as well.

This is slightly more verbose, but if we add default values to the
var() function, we can chop it down a bit:

comment {
  var-background: var(background2, white);
  var-background2: var(background, silver);
  background-color: var(background);
}

This seems acceptable to me.  I'll add an example to the Variables
spec about this.

~TJ

Received on Tuesday, 15 May 2012 00:16:01 UTC