Re: [css-color][css-transitions] Interpolation between currentcolor keyword and actual color value

On Sun, Apr 17, 2016 at 6:05 PM, Xidorn Quan <w3c@upsuper.org> wrote:
> When we are implementing -webkit-text-fill-color, we found an issue with
> transition due to we always computing "currentcolor" to an actual color
> value for interpolation rather than keeping it an computed value. [1]
>
> This raises a question about how "currentcolor" should be interpolated
> with an actual color value, given it is a computed value? The spec
> doesn't say anything about this.
>
> A simple example code is:
> @keyframes t {
>   0% {
>     color: #f00;
>     -webkit-text-fill-color: currentcolor;
>   }
>   100% {
>     color: #0f0;
>     -webkit-text-fill-color: #00f;
>   }
> }
>
> This code works in Firefox Nightly and all other major browser engines.
> And there are three different behaviors:
> 1. WebKit interpolates between #f00 (color at 0%) and #00f
> (text-fill-color at 100%), and Gecko currently has the same behavior,
> though somehow more buggy.
> 2. Blink treats currentcolor and #00f as uninterpolatable, so in the
> front 50%, it changes between #f00 and #808000, and then it becomes a
> solid #00f.
> 3. Edge treats currentcolor of text-fill-color at 0% as white somehow,
> and interpolates that with #00f.
>
> Edge's behavior doesn't make sense at all, and Blink's behavior looks
> conforming given the spec doesn't say anything currently, but it seems
> WebKit's behavior is the most sensible one in the three.
>
> Furthermore, if currentcolor is a computed value, the most ideally
> effect is probably making currentcolor follows the value of color at
> every moment, so at 50% of the transition, the used value of
> text-fill-color should be ((#f00 + #0f0) / 2 + #00f) / 2, rather than
> WebKit's behavior which is (#f00 + #00f) / 2.
>
> However, that could add much complexity to implementation. If there is
> no actual usecase, it is probably not worth that effort. Also if we
> choose this hard way, it could be a breaking change when switch
> currentcolor to a computed value for some cases.
>
> So I propose we can probably say something like, when one value is
> currentcolor and the other value is an actual color, treat currentcolor
> as its current used value at the given moment in advance.
>
> What do you think?
>
>
> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1260543

Blink's behavior is currently the spec-compliant one, unfortunately.
currentcolor doesn't simplify at computed-value time, and so you can't
represent the intermediate color.

To fix this well, we need to add some way to represent the
intermediate value - this means adding a color-blending function.  I
have a bad version of that in Colors 4 currently, but need to fix it
up to work better.  Once we have that, you can have the intermediate
color be rgb-blend(currentcolor, #00f 50%) or whatever (stealing
syntax from cross-fade()), and transitions will be possible.  This
will produce the behavior you say is "ideal" but "complex".  However,
it's probably not that complex if it's just the result of evaluating
the preceding expression, is it?

I'm not aware of any plans to "switch currentcolor to a computed value
for some cases" - can you elaborate?

~TJ

Received on Monday, 18 April 2016 21:43:47 UTC