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

On Fri, Apr 22, 2016 at 10:48 AM, L. David Baron <dbaron@dbaron.org> wrote:
> On Monday 2016-04-18 14:43 -0700, Tab Atkins Jr. wrote:
>> I'm not aware of any plans to "switch currentcolor to a computed value
>> for some cases" - can you elaborate?
>
> We've agreed to switch currentcolor to being a computed value.  We
> errata'd css-color-3 to do that:
> https://www.w3.org/Style/2011/REC-css3-color-20110607-errata.html#s.4.5
> and made it such in css-color-4:
> https://drafts.csswg.org/css-color-4/#currentcolor-color

Ah, Xidorn's wording confused me!  In particular, if currentcolor is
turned into an RGBA at computed-value time, then there's never a
problem at all and animations work exactly like animating between px
and em does; the entire issue is that we've specced it to not become
RGBA until used-value time, which instead puts us in a "px vs %"
situation, and we need a calc() equivalent for colors to represent the
intermediate animated value.

(I think you and he use the term "computed value" to mean something
different than I do - I'd call "1em" a "computed value", because it's
absolutized at computed-value time, while "width: 10%" is a "used
value".)

> In our implementation (and I would think in others too) this needs
> to be implemented per-property.  So we have some properties handling
> currentcolor the new way (as a computed value) and others falling
> back to the old way (which doesn't need to be done per-property and
> is thus within the generic color handling).
>
> We've had to do things the new way for properties where currentcolor
> is the initial value; text-emphasis-color and
> -webkit-text-fill-color depend on the change.  (Though for some
> legacy properties we don't handle currentcolor this way, but instead
> have a separate -moz-use-text-color that predates currentcolor.)
>
> But for most of these properties we have code to treat the computed
> value as being a color for animation purposes so that it does get
> animated.  To fix the above compatibility bug Xidorn just removed
> that code for text-emphasis-color and -webkit-text-fill-color so
> they don't animate between currentcolor and a non-currentcolor
> value, because of compatibility problems with
> -webkit-text-fill-color, in
> https://bugzilla.mozilla.org/show_bug.cgi?id=1260543 .
>
> I'd been hesitant to make the change for other properties because it
> would break animations that authors expect to work.  But now that I
> realize those animations don't work for -webkit-text-fill-color, I
> suspect they might all not work in Blink / WebKit, and there's no
> compatibility risk, although I think this needs to be tested
> per-property (which I haven't done).

We're also inconsistent right now:

<!DOCTYPE html>
<div class=foo>foo</div>
<style>
.foo { width: 100px; height: 100px; border: thick dotted; font-size:
70px; animation: foo 2s infinite alternate; }

@keyframes foo {
  from { color: white; background-color: white;
-webkit-text-fill-color: currentcolor; border-color: currentcolor;}
  to { color: black; background-color: lime; -webkit-text-fill-color:
lime; border-color: lime; }
}
</style>

As you can see, border-color treats "currentcolor" as turning into
RGBA at computed-value time; as a result, it constantly tracks the
'color' value and updates its animation, just like an animation using
both "em" values and font-size would.

On the other hand, -webkit-text-fill-color treats it as turning into
RGBA at used-value time, so it's unanimatable and instead gets the
"flip at 50% behavior - in the first half of the animation it holds
the value "currentcolor" (and thus tracks 'color' as it animates from
white to black), and in the second half it holds the value "lime".
(You can see it just after the 50% transition, as the bg is still in
the middle of its white=>lime transition and is thus paler.)

If we were completely consistent, both would act as
-webkit-text-fill-color does here.  If we added a blend() function and
used it for interpolation, the reverse would happen in practice; both
would act like border-color does here.  Decide which one you want, and
we can make sure it happens.

> The spec currently requires (4), but we're hoping in the long term
> to make it something more like but slightly better than (3), where
> the animation treats currentcolor as a computed value so it doesn't
> interpolate changes from currentcolor to currentcolor when color
> changes (which is the problem that caused bug 1260543, because that
> created a -webkit-text-fill-color value that inherited to a
> descendant that specified color, and then overrode that color) but
> that it does animate between currentcolor and real color values.

This is solved by a blend() function, as I outlined above;
"currentcolor" to "currentcolor" is no change and so no transition
occurs, but "currentcolor" to "red" is animated with
"blend(currentcolor, red X%)" (even if the currentcolor was, at the
time, red).

> My main worries about compatibility risk are for the properties
> currently in group (2) and for fill and stroke in group (1), since
> if we change them to group (4) we might never be able to change them
> back, because people will depend on them not animating.
>
> I haven't tested what other implementations do here; there are a
> *lot* of cases to test.  I'm curious if other implementors can
> explain what state their implementations are in here (perhaps a

> But my general concern here is that
> the group is making potentially-breaking changes, and then adding
> dependencies on those changes, before implementations have had a
> chance to test that they're actually safe changes to make.

The currentcolor change was finally resolved on in the May 2012
Hamburg F2F, just short of *4 years ago*; it was added to the errata
some time after that.  Implementations have definitely had their
chance to check that this is safe.

Since they've instead drug their feet on making the change, it's
possible we might only *now* discover that it's unsafe, but I don't
think it's reasonable to blame the *CSSWG* for that. ^_^

(I lived in fear for several years about the "make every property
animatable, with a 50% flip if nothing better is defined" thing, but
it looks like we've been doing it right for a while, so it's probably
safe.  Whew!)

~TJ

Received on Friday, 22 April 2016 19:26:46 UTC