SVG, CSS, and Canvas linear gradients

CSS defines the transparent keyword as meaning transparent black - rgba(0,0,0,0).

But, because when authors use the transparent keyword, they are actually expecting a transition to transparent with no colour change, the CSS Images Level 3 spec says that the gradient colour values must be pre-multiplied. That is, the colour at each stop must be multiplied by it's alpha value and then that resulting value is used as input to the gradient.

The reason that premultiplied colours cause this behaviour change is because when using premultiplied colours, you are essentially saying that a colour has an influence proportional to it's alpha.

Porter Duff define this in their paper, the definition of premultiplied colours is: The pixel is alpha covered by the colour (r / alpha, g / alpha, b / alpha).

Pre multiplied colours are also very useful for image operations such as down-sampling. Because it makes intuitive sense that the influence of a pixel to the down sampled image should be proportional to that pixels alpha, since the alpha of that pixel will be merged into the alpha of the pixels around it.

But I can't resolve that thinking with linear gradients. That is, I can't make an argument where it makes intuitive sense to use premultiplied colours, except of course for the special case that is the transparent keyword, which really should have just been a special case rather than being defined to be transparent black. The way it is now, it feels like CSS wants to treat the keyword 'transparent' as a premultiplied value, where the colour goes away as the alpha drops to zero, while the other author specified values are not. An example of this is rgba(255, 0, 0, 0), which when pre-multiplied, becomes (0, 0, 0, 0), or equivalent to 'transparent'. But surely the author intended a transition to red as the transition to transparent also occurs?

svg

canvas: 1. canvas gradient, 2. manually drawn gradient, 3. manually drawn premultiplied gradient

css