W3C home > Mailing lists > Public > www-style@w3.org > January 2011

Re: [CSS3] support for linear-gradients & radial-gradients

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 13 Jan 2011 10:05:55 -0800
Message-ID: <AANLkTik5QHeQ8ZV2mqqphnmQu4krBEwcmQL_FQ-h_utD@mail.gmail.com>
To: Alan Gresley <alan@css-class.com>
Cc: Simon Fraser <smfr@me.com>, Peter Beverloo <peter@lvp-media.com>, Irfan Mir <theirf@gmail.com>, www-style@w3.org
On Thu, Jan 13, 2011 at 1:39 AM, Alan Gresley <alan@css-class.com> wrote:
> On 13/01/2011 4:26 AM, Tab Atkins Jr. wrote:
>>
>> On Wed, Jan 12, 2011 at 7:19 AM, Alan Gresley<alan@css-class.com>  wrote:
>
> [snip]
>>>
>>> Why does this have to be a bug? The current behavior as seen in Gecko and
>>> WebKit is what one should expect from<color>  to transparent. I have seen
>>> it
>>> said that this notation rgba(0,0,0,0) is transparent. This notation
>>> rgba(255,255,255,0) is also transparent. The later is the type of
>>> transparent that both Gecko and WebKit want to change to. Why?
>>
>> I don't understand what you are trying to say or ask here.
>
>
> Simply that the keyword 'transparent' should not be confused with alpha
> transparency. As it says in CSS-Color [1] for the keyword 'transparent'.
>
>
>  | transparent
>  |   Fully transparent. This keyword can be considered a shorthand for
>  |   transparent black, rgba(0,0,0,0), which is its computed value.
>
>
> So 'transparent black' is not the same as 'transparent' but the keyword
> 'transparent' can be considered a shorthand for transparent black. CSS2.1 is
> more explicit in suggesting that 'transparent' is not a <color>. In 14.2.1
> [2] for background-color we have this (emphasis added).
>
>  | This property sets the background color of an element, either a
>  | <color> value *or* the keyword 'transparent', to make the underlying
>  | colors shine through.

CSS2.1 didn't have any notation for non-opaque colors, and so the
editors apparently thought that it was easier to refer to
'transparent' specially.  This turned out to be a mistake, and luckily
CSS3 Color has a proper way to refer to non-opaque colors, so we can
give 'transparent' a proper definition, which we did - it's
rgba(0,0,0,0).


>>> A transparent color does not have a point so it can not exist in any
>>> colorspace. It does not exist as a color apart from some concept which is
>>> very ambivalent.
>>
>> No, transparent colors exist perfectly fine.
>
>
> I should have said that the keyword value "transparent' is not a <color> and
> it does not have any point in any colorspace where all values of <color> do
> have a points within colorspace. You use this term "transparent colors."
> Should that really be colors with alpha transparency?

Yes, 'transparent' is a color.  It's rgba(0,0,0,0), in the sRGBA
colorspace (sRGB augmented with an alpha dimension).  It has a similar
definition in all other colorspaces.


>>> As gradients are currently implemented by Gecko and WebKit, there are
>>> only 4
>>> gradients that run in a direct line through sRGB colorspace. They are
>>> White
>>> to Black, Aqua to Red, Fuchsia to Lime and Yellow to Blue. The rest of
>>> the
>>> gradients from opaque<color>  to opaque<color>  either run through sRGB
>>> colorspace as cubic Bézier curve or quartic Bézier curve. If gradients
>>> become interpolated in premultiplied space then any gradient from<color>
>>>  to
>>> transparent would run in a direct line in through sRGB colorspace.
>>
>> No, all opaque colors are interpolated along a straight line in sRGB
>> space.  It doesn't matter whether you're using premultiplied colors or
>> not, as both color-spaces treat opaque colors the same.
>
> I made a completely wrong statement. Gradients from <color> point to <color>
> are interpolated along a straight line in sRGB if they follow particular
> planes within sRGB. I reason that some gradients, may travel a direct line
> and miss precise <color> points, in which case they use the color of the
> nearest <color> point (maybe rare in SRGB which has 16581376 colors). Is
> this a fare statement to make?

I'm not sure, because I don't understand what you're trying to say.
Yes, a color at any given point in a transition is rounded to the
nearest whole color in practice - halfway between 'white' and 'black'
is rgb(127.5,127.5,127.5), after all, which must be rounded up or
down.  But that's an irrelevant implementation detail.

Am I missing a more pertinent question?


>>> I don't understand why the CSS WG or implementers would want a CSS
>>> gradient
>>> to behave differently from a SVG gradient. A SVG gradient from<color>  to
>>> transparent is the same as the current Gecko and WebKit implemented CSS
>>> gradient which is interpolation in un-premultiplied space.
>>
>> SVG gradients don't use RGBA colors - they have RGB colors and then,
>> separately, an opacity.  Implementations allow the SVG colors to be
>> rgba, though, and when that occurs they want to do interpolation in
>> premultiplied space, same as CSS.
>
> Can you please clarify something, so I can fully understand? Theses
> questions are pertaining to CSS gradients.
>
> 1. Is a gradient from blue (#0f0) to yellow (#ff0) (midway way point is
> #7f7f7f) interpolated in premultiplied space or un-premultiplied space?

Both.  Opaque colors transition the same way in both colorspaces.


> 2. Is a gradient from bluish rgba(0,255,0,0.5) to yellowish
> rgba(255,255,0,0.5) (midway way point is rgba(127,127,127,0.5)) interpolated
> in premultiplied space or un-premultiplied space?

Both.  In general, colors with the same alpha transition the same way
in both colorspaces.

The only difference between premultiplied and non-premultiplied is
when you're transitioning between colors with different alphas.


>>> Another issue is how gradients from<color>  to transparent on a dark
>>> background become dirty. This is seen in this test.
>>>
>>> <http://css-class.com/test/css/colors/color-layer-above-below.htm>
>>>
>>> Example 5 is a SVG. Example 9, 10 and 11 are what gradients from<color>
>>>  to
>>> transparent would look like if interpolated in un-premultiplied space. At
>>> the bottom of the viewport is some buttons to change the background
>>> color.
>>> Underneath the test are various screenshots.
>>>
>>> <http://css-class.com/test/css/colors/gradient-test1.htm>
>>>
>>> The second example for "yellow - transparent" shows yellow polluting the
>>> background. The beginnings of the gradient don't fall of quick enough in
>>> intensity and hides the backgrounds in some examples.
>>
>> What you're seeing is the fact that transitions from opaque colors to
>> transparent in non-premultiplied space get darker as they progress.
>
> This is not true for all colors. I think you use the word darker loosely
> here. A gradient from blue to transparent (on a white background) get
> gradually lighter along the full projectory of the gradient. At the same
> time the same gradient get gradually lest saturated along the full
> projectory of the gradient. The only thing constant is it's hue.

No, I meant precisely what I said.  *All* colors get darker for the
first half of their transition toward 'transparent' if you do the
transition in non-premultiplied rgba space, because you're
transitioning the color components toward black.

That is, the halfway point between 'blue' and 'transparent' in
non-premultiplied rgba space is rgba(0,0,127,.5).  On the other hand,
the halfway point in premultiplied rgba space is rgba(0,0,255,.5).
The former is clearly darker than the latter, for the same reason
rgb(0,0,127) is clearly darker than rgb(0,0,255).

Now, even though the color is darkening, the final pixel color you see
after compositing it onto the background color may indeed be lighter,
depending on the background.  That's irrelevant.  You've confused
yourself by thinking about the final pixel colors before; what matters
is the actual colors being used, not what you get after you composite
all of them together.


>> Try doing a transition from opaque white to transparent over a white
>> background, and you'll see it very clearly - you'll get an image that
>> starts white, darkens to gray, and then lightens to white again.
>
> Well this is a good example. The same thing happens in SVG.
>
> <http://css-class.com/test/temp/gradient-white-trans.svg>

Yes, because SVG tracks opacity separately from color, like I said
before.  If you transition color and opacity separately, you get
results identical to transition in non-premultiplied space.


> If this exist in SVG gradients, why can't we keep the current behavior with
> Gecko and WebKit in CSS gradients?

Because it's *not* what the behavior of SVG gradients (they have a
different mechanism and can't be compared), and it's an undesirable
behavior in general.


> I would really like to see both types of gradients (<color> to transparent)
> with non-premultiplied and premultiplied interpolation in CSS.

As far as I can tell, there's no benefit to authors from being able to
transition in non-premultiplied space.  It does the wrong thing in the
general case.


> A question for those who know SVG. It it possible to create a SVG gradient
> from <color> to transparent with premultiplied interpolation? Something like
> this.
>
> <http://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperty>

Again, SVG doesn't know about non-opaque colors at all, so the
question of whether the colorspace is premultiplied or not is
meaningless.

That said, no, you can't mimic the effects of transitioning in
premultiplied space.

~TJ
Received on Thursday, 13 January 2011 18:06:49 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:36 GMT