- From: L. David Baron <dbaron@dbaron.org>
- Date: Fri, 22 Apr 2016 10:48:12 -0700
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: Xidorn Quan <w3c@upsuper.org>, www-style list <www-style@w3.org>, Brian Birtles <bbirtles@mozilla.com>
- Message-ID: <20160422174812.GA15079@pescadero.dbaron.org>
On Monday 2016-04-18 14:43 -0700, Tab Atkins Jr. wrote: > 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? 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 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). But I'm also hesitant to change other properties, or to leave things in this situation for a long time, because I'm worried about the Web becoming dependent on animations *not* working (as happened with -webkit-text-fill-color). I'm also hesitant to leave things in this situation for a long time because I'm worried that the Web might become dependent on having some properties behave in one way and some properties behave in the other way, either for animation or non-animation reasons. Right now Gecko does do animations from a currentcolor to non-currentcolor value for things like border-color. Essentially, depending on the property, we now have four different behaviors for currentcolor: 1. resolved to a color at computed-value time (fill, stroke, gradient color stops, shadow colors, background-color, flood-color, lighting-color, stop-color) 2. resolved to a color at computed-value time when specified explicitly, but at used-value time when it's the initial value (via -moz-use-text-color, which predates currentcolor), and animated as though it was resolved to a color at computed-value time either way (border-color, outline-color, column-rule-color) 3. resolved to a color at used-value time, but animated as though it was resolved to a color at computed-value time (text-decoration-color) 4. resolved to a color at used-value time, and not animated between currentcolor and color values (text-emphasis-color, -webkit-text-fill-color) 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. 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 better state for future risk). 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. -David -- 𝄞 L. David Baron http://dbaron.org/ 𝄂 𝄢 Mozilla https://www.mozilla.org/ 𝄂 Before I built a wall I'd ask to know What I was walling in or walling out, And to whom I was like to give offense. - Robert Frost, Mending Wall (1914)
Received on Friday, 22 April 2016 17:48:43 UTC