I recently had a great discussion with Louis Hoebregts (Mamboleoo) in the CodePen devs Slack about the differences between currentColor and transitions in -webkit and Gecko browsers. Louis found what seems to be a bug in the rendering of transitions of computed values like currentColor, only we differ on which browser we think is doing it right!

The first part of our puzzle is currentColor, which is a CSS keyword that dictates an element’s color should be equal to the computed color of its parent or first ancestor with a valid color value or browser default (usually black), in that order. Kind of like how border-color inherits the color property in the normal inheritance structure, only for every element.

The next element in the discussion is the CSS transition property:

transition: {property} {duration} {timing-function} {delay};

transition tells the browser that when {property} changes, we want the change to be animated over {duration}. Thus the transition property has a minimum of 2 values: {duration} and {property}.

Let’s see what the bug looks like.

See the Pen Transition issue with currentColor full by Smokie Lee (@xtoq) on CodePen.

div {
  background: currentcolor;
  color: black;
  display: inline-block;
  height: 40vmax;
  transition: 5s background;
  width: 40vmax;
}
div:hover {
  color:silver;
}

div:nth-child(2) {
  transition: 5s color;
}

In Firefox, both divs show a transition, while in Chrome only the second div with the color transition shows (the first div just switches immediately without a transition). I believe that Firefox is actually displaying this incorrectly, while Chrome is following the spec for transitions.

Specifically:

Implementations must not start a transition when the computed value of a property changes as a result of declarative animation (as opposed to scripted animation).

In programming, a declarative action is when you program what you would like to happen and let the computer determine how to do it, as opposed to imperative (called scripted in the MDN spec) in which you program how you want to do something. In this case, CSS animations and transitions are declarative (relying on the browser/computer to figure out how to render) while most Javascript animations are imperative/scripted. (For more details on the differences in general programming, read Philip Roberts’ article Imperative vs Declarative.)

The spec is saying that transitions should not start if the computed value (such as currentColor) changes because of a declarative (CSS) animation. Therefore Chrome’s behavior of only showing the transition on the 2nd div is correct because we’re transitioning on an actual value instead of a computed one. Firefox is not respecting the spec.

If you’ve got something to say, leave a comment below or shout to me on Twitter. For a more detailed discussion of the whys and hows of transitions on currentColor, there’s a great email thread from roughly 5 years ago that discusses it.

Also check out Louis’ website, his other Codepen work or follow him on Twitter.


Further reading:

  1. shrpne
    Dec 14, 2016

    Looks like Chrome behavior and spec are not good, because they make such a power things as currentColor and inherit values useless

    Reply