ArchiveOrangemail archive

www-style.w3.org


(List home) (Recent threads) (201 other W3C lists)

Subscription Options

  • RSS or Atom: Read-only subscription using a browser or aggregator. This is the recommended way if you don't need to send messages to the list. You can learn more about feed syndication and clients here.
  • Conventional: All messages are delivered to your mail address, and you can reply. To subscribe, send an email to the list's subscribe (we seem to have lost it) address with "subscribe" in the subject line.
  • Moderate traffic list: up to 30 messages per day
  • This list contains about 30,847 messages, beginning Mar 2011
  • 11 messages added yesterday
Report the Spam
This button sends a spam report to the moderator. Please use it sparingly. For other removal requests, read this.
Are you sure? yes no

Order of color-stop fixup

Ad
Tab Atkins Jr. 1313104385Thu, 11 Aug 2011 23:13:05 +0000 (UTC)
Right now, the color-stop fixup rules are:

1. If the first and last color stops don't have a position, make them
0% and 100%.
2. If any color-stop is mis-ordered, shift it so it's not.
3. If any other color-stops don't have a position, evenly distribute them.

Our implementation experience showed that the ordering of #2 and #3
makes it slightly harder to do transitions of gradients.  We'd like to
do as much of the transition on specified values as possible, and
defer computations that need layout information until the very end.
As such, Shane (new CSSWG member, dude who's doing the experimenting
with gradient transitions) suggested I swap steps 2 and 3, and further
make transitions operate *before* step 3, so the fixup is really a
super-final step done *just* before image generation.

Separately, Brian Mantheos brought up what I believe is the same
concern, where he'd prefer to do step 3 before step 2.

I don't have a preference either way.  Both produce smooth
transitions, they just result in slightly different positions for
auto-placed color-stops sometimes.

Does anyone have objections to me swapping these two steps?

~TJ
Brian Manthos 1313105056Thu, 11 Aug 2011 23:24:16 +0000 (UTC)
Two corrections:
(1) Drop the e in the name. ;)
(2) I brought up an example suggesting we might want to be more explicit for calc.  I think the current rules are fine.

-----Original Message-----
From:  [mailto:] On Behalf Of Tab Atkins Jr.
Sent: Thursday, August 11, 2011 4:11 PM
To: www-style list
Subject: [css3-images] Order of color-stop fixup

Right now, the color-stop fixup rules are:

1. If the first and last color stops don't have a position, make them 0% and 100%.
2. If any color-stop is mis-ordered, shift it so it's not.
3. If any other color-stops don't have a position, evenly distribute them.

Our implementation experience showed that the ordering of #2 and #3 makes it slightly harder to do transitions of gradients.  We'd like to do as much of the transition on specified values as possible, and defer computations that need layout information until the very end.
As such, Shane (new CSSWG member, dude who's doing the experimenting with gradient transitions) suggested I swap steps 2 and 3, and further make transitions operate *before* step 3, so the fixup is really a super-final step done *just* before image generation.

Separately, Brian Mantheos brought up what I believe is the same concern, where he'd prefer to do step 3 before step 2.

I don't have a preference either way.  Both produce smooth transitions, they just result in slightly different positions for auto-placed color-stops sometimes.

Does anyone have objections to me swapping these two steps?

~TJ
Tab Atkins Jr. 1313105424Thu, 11 Aug 2011 23:30:24 +0000 (UTC)
On Thu, Aug 11, 2011 at 4:22 PM, Brian Manthos  wrote:
> Two corrections:
> (1) Drop the e in the name. ;)!_!  I've misread your name this entire time somehow.


> (2) I brought up an example suggesting we might want to be more explicit for calc.  I think the current rules are fine.

Ah, I misunderstood the intent of your example.  (Brian had sent me an
example where all of the color-stops were using calc() with lengths
and percentages.)

~TJ
Shane Stephens 1313111157Fri, 12 Aug 2011 01:05:57 +0000 (UTC)
I'd like to swap the order of (2) and (3) because:

* (3) can be done when the style is applied (i.e. you don't need to know the
box dimensions in order to evenly distribute stops), but (2) can only be
done at render time (percentage values resolve relative to the size of the
container).
* webkit currently interpolates applied styles, not renderable styles (this
also means our implementation can't make use of the size of the container
while interpolating)
* it's difficult (not impossible, but difficult) to interpolate between an
implicitly placed stop and an explicitly placed stop, so it's nice to be
able to resolve implicitly placed stops before interpolating.

For example, interpolating between:

linear-gradient(red 20%, white 20px, blue, black 100%)
and
linear-gradient(red 0%, white 20%, blue 40%, black 100%)

If we need to defer spacing until we've resolved where the white stop is,
then in webkit we'd need to represent a 50% interpolation for the blue stop
as something like [auto@50%, 40%@50%] - i.e. a deferred interpolation
calculation of 50% between implicit placement and 40% placement. This then
needs to resolve at render time based on the current size of the container
and the location of the white and black stops (put blue halfway between
white and black, then interpolate halfway between that and the 40% point).
Of course if the container size is changing then it's not even the start
location of the blue stop that you're interpolating from but instead where
the start location would be if the container were the current size (it's
difficult to know how much this matters. I'll build a demo).

On the other hand, if we can space at apply time, then this turns into:
linear-gradient(red 20% + 0px, white 20px, blue 50% + 10px, black 100%)
and
linear-gradient(red 0%, white 20%, blue 40%, black 100%)

and we can then interpolate the blue stop at 50% as [45% + 5px], which is
simpler to calculate and represent. Of course, the white stop may well still
be shifted at render time because it's occluded by the red stop, but I'd
like that not to impact the position of the blue stop.

Hope this explains things a bit.

Cheers,
    -ShaneOn Thu, Aug 11, 2011 at 4:29 PM, Tab Atkins Jr. wrote:

> On Thu, Aug 11, 2011 at 4:22 PM, Brian Manthos 
> wrote:
> > Two corrections:
> > (1) Drop the e in the name. ;)
>
> !_!  I've misread your name this entire time somehow.
>
>
> > (2) I brought up an example suggesting we might want to be more explicit
> for calc.  I think the current rules are fine.
>
> Ah, I misunderstood the intent of your example.  (Brian had sent me an
> example where all of the color-stops were using calc() with lengths
> and percentages.)
>
> ~TJ
>
>
Brian Manthos 1313119617Fri, 12 Aug 2011 03:26:57 +0000 (UTC)
How are you addressing these interpolation scenarios without knowing more about the box:
i. corner-to-corner linear gradients (aspect ratio impacts interpolation of the intermediate angles)
ii. cover/contain radial gradients (distance from corners/sides impacts interpolation of the radii)


I would expect a number of properties that are sensitive to box size wouldn't interpolate properly (or at all) with the system you described.

Interpolating before render time makes sense, but interpolating before layout/sizing doesn't make sense to me.  It just seems way too early in the pipeline.

If we continue down this path, it suggests that any and all properties with interpolation impacted by box size or ratio need to be revised or declared incompatible with interpolation.  That seems like the wrong approach for CSS going forward.  Maybe I'm misunderstanding.


Getting back to the original question...

Example A
linear-gradient(black, red -200%, white, blue)

A - ED 5.4 current [2,3]
linear-gradient(black 0%, red 0%, white 50%, blue 100%)
50% red to white, then 50% white to blue

A - ED 5.4 proposed [3,2]
linear-gradient(black 0%, red 0%, white 0%, blue 100%)
100% white to blue


Example B
linear-gradient(black 100px, red 20%, white, blue)

B, 200px box - ED 5.4 current [2,3]
linear-gradient(black 100px, red 20%, white, blue 100%)
linear-gradient(black 50%, red 20%, white, blue 100%)
linear-gradient(black 50%, red 50%, white, blue 100%)
linear-gradient(black 50%, red 50%, white 75%, blue 100%)
50% black, then 25% red to white, then 25% white to blue

B, 400px box - ED 5.4 current [2,3]
linear-gradient(black 100px, red 20%, white, blue 100%)
linear-gradient(black 25%, red 20%, white, blue 100%)
linear-gradient(black 25%, red 25%, white, blue 100%)
linear-gradient(black 25%, red 25%, white 62.5%, blue 100%)
25% black, then 37.5% red to white, then 37.5% white to blue

B, 200px box - ED 5.4 proposed [3,2]
linear-gradient(black 100px, red 20%, white, blue 100%)
linear-gradient(black 100px, red 20%, white 60%, blue 100%)
linear-gradient(black 50%, red 20%, white 60%, blue 100%)
linear-gradient(black 50%, red 50%, white 60%, blue 100%)
50% black, then 10% red to white, then 40% white to blue

B, 400px box - ED 5.4 proposed [3,2]
linear-gradient(black 100px, red 20%, white, blue 100%)
linear-gradient(black 100px, red 20%, white 60%, blue 100%)
linear-gradient(black 25%, red 20%, white 60%, blue 100%)
linear-gradient(black 25%, red 25%, white 60%, blue 100%)
25% black, then 35% red to white, then 40% white to blue


While it might be because I'm used to the current behavior, looking at the examples above I prefer the existing behavior. Why?  Because the even distribution of unspecified stops is consistently respected.  With the [3,2] proposal, the "overlapping stop correction" (2) trumps the even distribution which (IMO) is undesirable.

I need to think about it some more, but just from the above I'm hesitant to change the order.


Also, Tab, I suspect rearranging (2) and (3) has other implications that would take me more time to work through.  I don't know if those implications are blocking or not, but it isn't a trivial change that's easy to evaluate.

-Brian

From: Shane Stephens [mailto:]
Sent: Thursday, August 11, 2011 6:04 PM
To: Tab Atkins Jr.
Cc: Brian Manthos; www-style list
Subject: Re: [css3-images] Order of color-stop fixup

I'd like to swap the order of (2) and (3) because:

* (3) can be done when the style is applied (i.e. you don't need to know the box dimensions in order to evenly distribute stops), but (2) can only be done at render time (percentage values resolve relative to the size of the container).
* webkit currently interpolates applied styles, not renderable styles (this also means our implementation can't make use of the size of the container while interpolating)
* it's difficult (not impossible, but difficult) to interpolate between an implicitly placed stop and an explicitly placed stop, so it's nice to be able to resolve implicitly placed stops before interpolating.

For example, interpolating between:

linear-gradient(red 20%, white 20px, blue, black 100%)
and
linear-gradient(red 0%, white 20%, blue 40%, black 100%)

If we need to defer spacing until we've resolved where the white stop is, then in webkit we'd need to represent a 50% interpolation for the blue stop as something like [auto@50%, 40%@50%] - i.e. a deferred interpolation calculation of 50% between implicit placement and 40% placement. This then needs to resolve at render time based on the current size of the container and the location of the white and black stops (put blue halfway between white and black, then interpolate halfway between that and the 40% point). Of course if the container size is changing then it's not even the start location of the blue stop that you're interpolating from but instead where the start location would be if the container were the current size (it's difficult to know how much this matters. I'll build a demo).

On the other hand, if we can space at apply time, then this turns into:
linear-gradient(red 20% + 0px, white 20px, blue 50% + 10px, black 100%)
and
linear-gradient(red 0%, white 20%, blue 40%, black 100%)

and we can then interpolate the blue stop at 50% as [45% + 5px], which is simpler to calculate and represent. Of course, the white stop may well still be shifted at render time because it's occluded by the red stop, but I'd like that not to impact the position of the blue stop.

Hope this explains things a bit.

Cheers,
    -ShaneOn Thu, Aug 11, 2011 at 4:29 PM, Tab Atkins Jr. <mailto:> wrote:
On Thu, Aug 11, 2011 at 4:22 PM, Brian Manthos <mailto:> wrote:
> Two corrections:
> (1) Drop the e in the name. ;)!_!  I've misread your name this entire time somehow.


> (2) I brought up an example suggesting we might want to be more explicit for calc.  I think the current rules are fine.
Ah, I misunderstood the intent of your example.  (Brian had sent me an
example where all of the color-stops were using calc() with lengths
and percentages.)

~TJ
Shane Stephens 1313122811Fri, 12 Aug 2011 04:20:11 +0000 (UTC)
On Thu, Aug 11, 2011 at 8:24 PM, Brian Manthos wrote:

>  How are you addressing these interpolation scenarios without knowing more
> about the box:****
>
> i. corner-to-corner linear gradients (aspect ratio impacts interpolation of
> the intermediate angles)****
>
> ii. cover/contain radial gradients (distance from corners/sides impacts
> interpolation of the radii)****
>
> ** **
>
> ** **
>
> I would expect a number of properties that are sensitive to box size
> wouldn’t interpolate properly (or at all) with the system you described.**
> **
>
> ** **
>
> Interpolating before render time makes sense, but interpolating before
> layout/sizing doesn’t make sense to me.  It just seems way too early in the
> pipeline.****
>
> ** **
>
> If we continue down this path, it suggests that any and all properties with
> interpolation impacted by box size or ratio need to be revised or declared
> incompatible with interpolation.  That seems like the wrong approach for CSS
> going forward.  Maybe I’m misunderstanding.
>Interpolating container-sensitive properties is still possible, it just
takes more work. I outlined how to do it in my previous email, but here it
is again:
(1) store non-resolved start and end values as part of the interpolated
result (e.g. [cover 30%, contain 70%] is the result of a 30% interpolation
between a cover gradient and a contain gradient)
(2) resolve start and end values against current size of container
(3) interpolate resolved values

Notice that there's an interesting twist here: the container size used is
the current size, not the size at the start (for cover) and end (for
contain). Obviously with a static container there's no difference, but what
happens if there's a dynamic container?

Interestingly, even if you do interpolate the renderable data rather than
the non-resolved values, you find yourself having to (1) store a snapshot of
the renderable state at the start, in order to be able to interpolate from
it; and (2) either guess at the container size at the end (actual knowledge
is not possible in the presence of animations that can be initiated by user
actions) or use the current size anyway.

Thinking about the problem further, take this case:
radial-gradient(center, ellipse contain, red, blue)
to
radial-gradient(center, ellipse contain, white, black)

The central question in my mind is: should the intermediate values of the
gradient obey contain? If they should (and I would argue that this makes
more sense) then you can't interpolate render-time data and you must store
the initial values in the interpolated result, as otherwise something like
this will result in a gradient that only covers 66% of the box after 1
second:

.box {
  width: 100px;
  height: 100px;
  background: radial-gradient(center, ellipse contain, red, blue);
  -webkit-transition-property: width, height, background;
  -webkit-transition-duration: 1s, 1s, 2s;
}

.box:hover {
  width: 200px;
  height: 200px;
  background: -webkit-radial-gradient(center, ellipse contain, blue, black);
}> Getting back to the original question…****
>
> ** **
>
> Example A****
>
> linear-gradient(black, red -200%, white, blue)****
>
> ** **
>
> A - ED 5.4 current [2,3]****
>
> linear-gradient(black 0%, red 0%, white 50%, blue 100%)****
>
> 50% red to white, then 50% white to blue****
>
> ** **
>
> A - ED 5.4 proposed [3,2]****
>
> linear-gradient(black 0%, red 0%, white 0%, blue 100%)****
>
> 100% white to blue****
>
> ** **
>
> ** **
>
> Example B****
>
> linear-gradient(black 100px, red 20%, white, blue)****
>
> ** **
>
> B, 200px box - ED 5.4 current [2,3]****
>
> linear-gradient(black 100px, red 20%, white, blue 100%)****
>
> linear-gradient(black 50%, red 20%, white, blue 100%)****
>
> linear-gradient(black 50%, red 50%, white, blue 100%)****
>
> linear-gradient(black 50%, red 50%, white 75%, blue 100%)****
>
> 50% black, then 25% red to white, then 25% white to blue****
>
> ** **
>
> B, 400px box - ED 5.4 current [2,3]****
>
> linear-gradient(black 100px, red 20%, white, blue 100%)****
>
> linear-gradient(black 25%, red 20%, white, blue 100%)****
>
> linear-gradient(black 25%, red 25%, white, blue 100%)****
>
> linear-gradient(black 25%, red 25%, white 62.5%, blue 100%)****
>
> 25% black, then 37.5% red to white, then 37.5% white to blue****
>
> ** **
>
> B, 200px box - ED 5.4 proposed [3,2]****
>
> linear-gradient(black 100px, red 20%, white, blue 100%)****
>
> linear-gradient(black 100px, red 20%, white 60%, blue 100%)****
>
> linear-gradient(black 50%, red 20%, white 60%, blue 100%)****
>
> linear-gradient(black 50%, red 50%, white 60%, blue 100%)****
>
> 50% black, then 10% red to white, then 40% white to blue****
>
> ** **
>
> B, 400px box - ED 5.4 proposed [3,2]****
>
> linear-gradient(black 100px, red 20%, white, blue 100%)****
>
> linear-gradient(black 100px, red 20%, white 60%, blue 100%)****
>
> linear-gradient(black 25%, red 20%, white 60%, blue 100%)****
>
> linear-gradient(black 25%, red 25%, white 60%, blue 100%)****
>
> 25% black, then 35% red to white, then 40% white to blue****
>
> ** **
>
> ** **
>
> While it might be because I’m used to the current behavior, looking at the
> examples above I prefer the existing behavior. Why?  Because the even
> distribution of unspecified stops is consistently respected.  With the [3,2]
> proposal, the “overlapping stop correction” (2) trumps the even distribution
> which (IMO) is undesirable.
>I'm just going to note here that the specification specifically recommends
against mixing pixel and percent stops; and that placing a stop at -200%
after a stop at 0% is not exactly a standard use case. Additionally:

Example 1:
linear-gradient(red -100%, white, green, black, blue)

Example 2:
linear-gradient(black, red -100%, white, green, black, blue)

Example 1 ED 5.4 current:
linear-gradient(red -100%, white -50%, green 0%, black 50%, blue 100%)

Example 2 ED 5.4 current:
linear-gradient(black 0%, red 0%, white 25%, green 50%, black 75%, blue
100%)

Why has adding a black stop before my explicitly specified red stop caused
all of my evenly spaced stops to shuffle up?  I asked for them to be spaced
between -100% and 100%.

Cheers,
    -Shane> **
>
> I need to think about it some more, but just from the above I’m hesitant to
> change the order.
>


> Also, Tab, I suspect rearranging (2) and (3) has other implications that
> would take me more time to work through.  I don’t know if those implications
> are blocking or not, but it isn’t a trivial change that’s easy to evaluate.
> ****
>
> ** **
>
> -Brian****
>
> ** **
>
> *From:* Shane Stephens [mailto:]
> *Sent:* Thursday, August 11, 2011 6:04 PM
> *To:* Tab Atkins Jr.
> *Cc:* Brian Manthos; www-style list
> *Subject:* Re: [css3-images] Order of color-stop fixup****
>
> ** **
>
> I'd like to swap the order of (2) and (3) because:****
>
> ** **
>
> * (3) can be done when the style is applied (i.e. you don't need to know
> the box dimensions in order to evenly distribute stops), but (2) can only be
> done at render time (percentage values resolve relative to the size of the
> container).****
>
> * webkit currently interpolates applied styles, not renderable styles (this
> also means our implementation can't make use of the size of the container
> while interpolating)****
>
> * it's difficult (not impossible, but difficult) to interpolate between an
> implicitly placed stop and an explicitly placed stop, so it's nice to be
> able to resolve implicitly placed stops before interpolating.****
>
> ** **
>
> For example, interpolating between:****
>
> ** **
>
> linear-gradient(red 20%, white 20px, blue, black 100%)****
>
> and****
>
> linear-gradient(red 0%, white 20%, blue 40%, black 100%)****
>
> ** **
>
> If we need to defer spacing until we've resolved where the white stop is,
> then in webkit we'd need to represent a 50% interpolation for the blue stop
> as something like [auto@50%, 40%@50%] - i.e. a deferred interpolation
> calculation of 50% between implicit placement and 40% placement. This then
> needs to resolve at render time based on the current size of the container
> and the location of the white and black stops (put blue halfway between
> white and black, then interpolate halfway between that and the 40% point).
> Of course if the container size is changing then it's not even the start
> location of the blue stop that you're interpolating from but instead where
> the start location would be if the container were the current size (it's
> difficult to know how much this matters. I'll build a demo).****
>
> ** **
>
> On the other hand, if we can space at apply time, then this turns into:***
> *
>
> linear-gradient(red 20% + 0px, white 20px, blue 50% + 10px, black 100%)***
> *
>
> and****
>
> linear-gradient(red 0%, white 20%, blue 40%, black 100%)****
>
> ** **
>
> and we can then interpolate the blue stop at 50% as [45% + 5px], which is
> simpler to calculate and represent. Of course, the white stop may well still
> be shifted at render time because it's occluded by the red stop, but I'd
> like that not to impact the position of the blue stop.****
>
> ** **
>
> Hope this explains things a bit.****
>
> ** **
>
> Cheers,****
>
>     -Shane****
>
> ** **
>
> On Thu, Aug 11, 2011 at 4:29 PM, Tab Atkins Jr. 
> wrote:****
>
> On Thu, Aug 11, 2011 at 4:22 PM, Brian Manthos 
> wrote:
> > Two corrections:
> > (1) Drop the e in the name. ;)****
>
> !_!  I've misread your name this entire time somehow.****
>
>
>
> > (2) I brought up an example suggesting we might want to be more explicit
> for calc.  I think the current rules are fine.****
>
> Ah, I misunderstood the intent of your example.  (Brian had sent me an
> example where all of the color-stops were using calc() with lengths
> and percentages.)
>
> ~TJ****
>
> ** **
>
Brian Manthos 1313127044Fri, 12 Aug 2011 05:30:44 +0000 (UTC)
Correct, you have specified two constraints that are conflicting.  The current spec chooses to respect the even distribution over the distribution length, since satisfying both is not possible.

-Brian

From: Shane Stephens [mailto:]
Sent: Thursday, August 11, 2011 9:18 PM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list
Subject: Re: [css3-images] Order of color-stop fixup


Example 1:
linear-gradient(red -100%, white, green, black, blue)

Example 2:
linear-gradient(black, red -100%, white, green, black, blue)

Example 1 ED 5.4 current:
linear-gradient(red -100%, white -50%, green 0%, black 50%, blue 100%)

Example 2 ED 5.4 current:
linear-gradient(black 0%, red 0%, white 25%, green 50%, black 75%, blue 100%)

Why has adding a black stop before my explicitly specified red stop caused all of my evenly spaced stops to shuffle up?  I asked for them to be spaced between -100% and 100%.
Shane Stephens 1313150086Fri, 12 Aug 2011 11:54:46 +0000 (UTC)
On Thu, Aug 11, 2011 at 10:28 PM, Brian Manthos wrote:

>  Correct, you have specified two constraints that are conflicting.  The
> current spec chooses to respect the even distribution over the distribution
> length, since satisfying both is not possible.
>Well, yes. The point is that either approach breaks a set of constraints and
hence "this approach breaks some constraints" is not in and of itself a
strong argument against one of the two.

Cheers,
    -Shane> ****
>
> ** **
>
> -Brian****
>
> ** **
>
> *From:* Shane Stephens [mailto:]
> *Sent:* Thursday, August 11, 2011 9:18 PM
> *To:* Brian Manthos
> *Cc:* Tab Atkins Jr.; www-style list
>
> *Subject:* Re: [css3-images] Order of color-stop fixup****
>
>  ** **
>
> ** **
>
> Example 1:****
>
> linear-gradient(red -100%, white, green, black, blue)****
>
> ** **
>
> Example 2:****
>
> linear-gradient(black, red -100%, white, green, black, blue)****
>
> ** **
>
> Example 1 ED 5.4 current:****
>
> linear-gradient(red -100%, white -50%, green 0%, black 50%, blue 100%)****
>
> ** **
>
> Example 2 ED 5.4 current:****
>
> linear-gradient(black 0%, red 0%, white 25%, green 50%, black 75%, blue
> 100%)****
>
> ** **
>
> Why has adding a black stop before my explicitly specified red stop caused
> all of my evenly spaced stops to shuffle up?  I asked for them to be spaced
> between -100% and 100%.****
>
> ** **
>
Brian Manthos 1313128057Fri, 12 Aug 2011 05:47:37 +0000 (UTC)
It seems unnecessary and error-prone to do the interpolation twice, in steps (1) and (3).

From: Shane Stephens [mailto:]
Sent: Thursday, August 11, 2011 9:18 PM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list
Subject: Re: [css3-images] Order of color-stop fixup

...
Interpolating container-sensitive properties is still possible, it just takes more work. I outlined how to do it in my previous email, but here it is again:
(1) store non-resolved start and end values as part of the interpolated result (e.g. [cover 30%, contain 70%] is the result of a 30% interpolation between a cover gradient and a contain gradient)
(2) resolve start and end values against current size of container
(3) interpolate resolved values
...
Shane Stephens 1313150120Fri, 12 Aug 2011 11:55:20 +0000 (UTC)
On Thu, Aug 11, 2011 at 10:46 PM, Brian Manthos wrote:

>  It seems unnecessary and error-prone to do the interpolation twice, in
> steps (1) and (3).
>OK, then can you come up with an alternative approach that still conserves
"contain" in the example I provided?

Cheers,
    -Shane> ****
>
> ** **
>
> *From:* Shane Stephens [mailto:]
> *Sent:* Thursday, August 11, 2011 9:18 PM
> *To:* Brian Manthos
> *Cc:* Tab Atkins Jr.; www-style list
>
> *Subject:* Re: [css3-images] Order of color-stop fixup****
>
>  ** **
>
> ...****
>
> Interpolating container-sensitive properties is still possible, it just
> takes more work. I outlined how to do it in my previous email, but here it
> is again:****
>
> (1) store non-resolved start and end values as part of the interpolated
> result (e.g. [cover 30%, contain 70%] is the result of a 30% interpolation
> between a cover gradient and a contain gradient)****
>
> (2) resolve start and end values against current size of container****
>
> (3) interpolate resolved values****
>
> ...****
>
Brian Manthos 1313150802Fri, 12 Aug 2011 12:06:42 +0000 (UTC)
Interpolate after knowing container size information rather than before...

-Brian

From: Shane Stephens [mailto:]
Sent: Friday, August 12, 2011 4:55 AM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list
Subject: Re: [css3-images] Order of color-stop fixup


On Thu, Aug 11, 2011 at 10:46 PM, Brian Manthos <mailto:> wrote:
It seems unnecessary and error-prone to do the interpolation twice, in steps (1) and (3).

OK, then can you come up with an alternative approach that still conserves "contain" in the example I provided?

Cheers,
    -Shane


From: Shane Stephens [mailto:<mailto:]
Sent: Thursday, August 11, 2011 9:18 PM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list

Subject: Re: [css3-images] Order of color-stop fixup

...
Interpolating container-sensitive properties is still possible, it just takes more work. I outlined how to do it in my previous email, but here it is again:
(1) store non-resolved start and end values as part of the interpolated result (e.g. [cover 30%, contain 70%] is the result of a 30% interpolation between a cover gradient and a contain gradient)
(2) resolve start and end values against current size of container
(3) interpolate resolved values
...
Shane Stephens 1313151922Fri, 12 Aug 2011 12:25:22 +0000 (UTC)
On Fri, Aug 12, 2011 at 5:05 AM, Brian Manthos wrote:

>  Interpolate after knowing container size information rather than
> before...
>Obviously I didn't explain the example clearly enough. Here's the CSS again.

.box {
  width: 100px;
  height: 100px;
  background: radial-gradient(center, ellipse contain, red, blue);
  -webkit-transition-property: width, height, background;
  -webkit-transition-duration: 1s, 1s, 2s;
}

.box:hover {
  width: 200px;
  height: 200px;
  background: -webkit-radial-gradient(center, ellipse contain, blue, black);
}

The only data of interest here is the gradient size. At the beginning of the
interpolation (unhovered), it's 50px (the ellipse is in the center of a
100px x 100px square and is contained within that square). After 2 seconds
(fully hovered) it's 100px.

If you use render-time interpolation, resolving sizes down to pixel values
before interpolation, then at 50% the size of this ellipse must be 75px
(50px x 0.5 + 100px x 0.5). However, 50% is 1 second into the animation, at
which point the box size is 200px x 200px, which means that halfway between
the gradient's interpolation it does not match the "contain" requirement,
even though the gradient has interpolated from "contain" to "contain". This
in turn means that the gradient is not a "contain" gradient at any point
during the interpolation except for the beginning and end.

I'm just not happy for an interpolation component that is the same at the
beginning and end of the interpolation to violate its specification
mid-interpolation. That would be something like saying that interpolating
between rgb(255, 0, 0) and rgb(255, 0, 255) could potentially have rgb(200,
27, 128) as a midpoint value.

Cheers,
    -Shane

**>
> -Brian****
>
> ** **
>
> *From:* Shane Stephens [mailto:]
> *Sent:* Friday, August 12, 2011 4:55 AM
>
> *To:* Brian Manthos
> *Cc:* Tab Atkins Jr.; www-style list
> *Subject:* Re: [css3-images] Order of color-stop fixup****
>
>  ** **
>
> ** **
>
> On Thu, Aug 11, 2011 at 10:46 PM, Brian Manthos 
> wrote:****
>
> It seems unnecessary and error-prone to do the interpolation twice, in
> steps (1) and (3).****
>
> ** **
>
> OK, then can you come up with an alternative approach that still conserves
> "contain" in the example I provided?****
>
> ** **
>
> Cheers,****
>
>     -Shane****
>
>  ****
>
>   ****
>
> *From:* Shane Stephens [mailto:] ****
>
> *Sent:* Thursday, August 11, 2011 9:18 PM
> *To:* Brian Manthos****
>
> *Cc:* Tab Atkins Jr.; www-style list****
>
>
> *Subject:* Re: [css3-images] Order of color-stop fixup****
>
>  ****
>
> ...****
>
> Interpolating container-sensitive properties is still possible, it just
> takes more work. I outlined how to do it in my previous email, but here it
> is again:****
>
> (1) store non-resolved start and end values as part of the interpolated
> result (e.g. [cover 30%, contain 70%] is the result of a 30% interpolation
> between a cover gradient and a contain gradient)****
>
> (2) resolve start and end values against current size of container****
>
> (3) interpolate resolved values****
>
> ...****
>
>  ** **
>
Tab Atkins Jr. 1313171901Fri, 12 Aug 2011 17:58:21 +0000 (UTC)
On Fri, Aug 12, 2011 at 5:23 AM, Shane Stephens  wrote:
> On Fri, Aug 12, 2011 at 5:05 AM, Brian Manthos 
> wrote:
>> Interpolate after knowing container size information rather than
>> before...
>
> Obviously I didn't explain the example clearly enough. Here's the CSS again.
> .box {
>   width: 100px;
>   height: 100px;
>   background: radial-gradient(center, ellipse contain, red, blue);
>   -webkit-transition-property: width, height, background;
>   -webkit-transition-duration: 1s, 1s, 2s;
> }
> .box:hover {
>   width: 200px;
>   height: 200px;
>   background: -webkit-radial-gradient(center, ellipse contain, blue, black);
> }
>
> The only data of interest here is the gradient size. At the beginning of the
> interpolation (unhovered), it's 50px (the ellipse is in the center of a
> 100px x 100px square and is contained within that square). After 2 seconds
> (fully hovered) it's 100px.
>
> If you use render-time interpolation, resolving sizes down to pixel values
> before interpolation, then at 50% the size of this ellipse must be 75px
> (50px x 0.5 + 100px x 0.5). However, 50% is 1 second into the animation, at
> which point the box size is 200px x 200px, which means that halfway between
> the gradient's interpolation it does not match the "contain" requirement,
> even though the gradient has interpolated from "contain" to "contain". This
> in turn means that the gradient is not a "contain" gradient at any point
> during the interpolation except for the beginning and end.
>
> I'm just not happy for an interpolation component that is the same at the
> beginning and end of the interpolation to violate its specification
> mid-interpolation. That would be something like saying that interpolating
> between rgb(255, 0, 0) and rgb(255, 0, 255) could potentially have rgb(200,
> 27, 128) as a midpoint value.This problem ("My constraints change in the middle of my animation!")
already exists in transitions.  Try this example:

<!DOCTYPE html>
<style>
div { -webkit-transition: width 1s linear; }
#foo { width: 50%; background: #bada55; }
#bar { width: 50%; background: cornflowerblue;
-webkit-transition-duration: 2s; }
#foo:hover { width: 90%; }
#foo:hover > #bar { width: 10%; }
</style>
<div id=foo><div id=bar>&nbsp</div></div>

You already have to watch the endpoints and adjust yourself if they
implicitly change.  If you just snapshot the used values of the
endpoints at the start of the animation, you'll be very wrong.

~TJ
Brian Manthos 1313179402Fri, 12 Aug 2011 20:03:22 +0000 (UTC)
"resolving sizes down to pixel values before interpolation"
We're missing each other apparently.

Resolve *nothing* before you have all the necessary data to do so.

-Brian

From: Shane Stephens [mailto:]
Sent: Friday, August 12, 2011 5:23 AM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list
Subject: Re: [css3-images] Order of color-stop fixup


On Fri, Aug 12, 2011 at 5:05 AM, Brian Manthos <mailto:> wrote:
Interpolate after knowing container size information rather than before...

Obviously I didn't explain the example clearly enough. Here's the CSS again.

.box {
  width: 100px;
  height: 100px;
  background: radial-gradient(center, ellipse contain, red, blue);
  -webkit-transition-property: width, height, background;
  -webkit-transition-duration: 1s, 1s, 2s;
}

.box:hover {
  width: 200px;
  height: 200px;
  background: -webkit-radial-gradient(center, ellipse contain, blue, black);
}

The only data of interest here is the gradient size. At the beginning of the interpolation (unhovered), it's 50px (the ellipse is in the center of a 100px x 100px square and is contained within that square). After 2 seconds (fully hovered) it's 100px.

If you use render-time interpolation, resolving sizes down to pixel values before interpolation, then at 50% the size of this ellipse must be 75px (50px x 0.5 + 100px x 0.5). However, 50% is 1 second into the animation, at which point the box size is 200px x 200px, which means that halfway between the gradient's interpolation it does not match the "contain" requirement, even though the gradient has interpolated from "contain" to "contain". This in turn means that the gradient is not a "contain" gradient at any point during the interpolation except for the beginning and end.

I'm just not happy for an interpolation component that is the same at the beginning and end of the interpolation to violate its specification mid-interpolation. That would be something like saying that interpolating between rgb(255, 0, 0) and rgb(255, 0, 255) could potentially have rgb(200, 27, 128) as a midpoint value.

Cheers,
    -Shane

-Brian

From: Shane Stephens [mailto:<mailto:]
Sent: Friday, August 12, 2011 4:55 AM

To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list
Subject: Re: [css3-images] Order of color-stop fixup


On Thu, Aug 11, 2011 at 10:46 PM, Brian Manthos <mailto:> wrote:
It seems unnecessary and error-prone to do the interpolation twice, in steps (1) and (3).

OK, then can you come up with an alternative approach that still conserves "contain" in the example I provided?

Cheers,
    -Shane


From: Shane Stephens [mailto:<mailto:]
Sent: Thursday, August 11, 2011 9:18 PM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list

Subject: Re: [css3-images] Order of color-stop fixup

...
Interpolating container-sensitive properties is still possible, it just takes more work. I outlined how to do it in my previous email, but here it is again:
(1) store non-resolved start and end values as part of the interpolated result (e.g. [cover 30%, contain 70%] is the result of a 30% interpolation between a cover gradient and a contain gradient)
(2) resolve start and end values against current size of container
(3) interpolate resolved values
...
Shane Stephens 1313458038Tue, 16 Aug 2011 01:27:18 +0000 (UTC)
On Fri, Aug 12, 2011 at 1:01 PM, Brian Manthos wrote:

>  “resolving sizes down to pixel values before interpolation“****
>
> We’re missing each other apparently.****
>
> ** **
>
> Resolve **nothing** before you have all the necessary data to do so.****
>
> **
>Ah, I apologize. I thought you were suggesting that the right gradient
representation for interpolation was percentages for stops and pixel values
for position and gradient size.

Coming back to the original topic, the WebKit animation pipeline currently
interpolates at apply time. As we've discussed it's still possible to make
gradient interpolation work correctly with this scheme, although as you've
pointed out it is more complicated than just interpolating further down the
stack. Unfortunately, making big changes to the pipeline is not something
I'm likely to be able to do, and it is anyway something I'm wary about - I
don't know the context around why the pipeline is the way it is.

As an implementation detail, it's easier to interpolate stops at the point
where WebKit does it if rules (2) and (3) of color-stop fixup are swapped.
It seems that:

* swapping these steps merely exchanges one constraint bias for another -
i.e. one approach is not more correct than the other
* if you are already interpolating lower down the stack, either approach is
of similar complexity
* only poorly specified gradients (i.e. with mixed pixel and percentage
values or clear order inversions) are impacted

With this in mind, do you have objections to swapping the two steps?

Cheers,
    -Shane
Brian Manthos 1313459232Tue, 16 Aug 2011 01:47:12 +0000 (UTC)
Yes, I object.

For the original two reasons:

(1)    It exchanges what I consider as a good rendering for a bad one.

(2)    Setting (1) aside for a moment, at best your proposed rendering is "as good" as the existing one, which isn't enough reason to go against the inertia/momentum of the spec as it stands (and the degree of interoperability of implementations we have thus far).

(3)    It's a local "fix" for a small portion of the larger problem, and as such (a) doesn't address the whole problem and (b) potentially becomes a "tail wagging the dog" precedent for all kinds of other potential changes across CSS to support (IMO) "interpolating at the wrong time".

Also note, in case you missed it, Tab replied [@ Fri 10:57 AM PST] with another example that presents a problem for the system you describe.  Unless I misunderstood his example.

-Brian

From: Shane Stephens [mailto:]
Sent: Monday, August 15, 2011 6:26 PM
To: Brian Manthos
Cc: Tab Atkins Jr.; www-style list
Subject: Re: [css3-images] Order of color-stop fixup

On Fri, Aug 12, 2011 at 1:01 PM, Brian Manthos <mailto:> wrote:
"resolving sizes down to pixel values before interpolation"
We're missing each other apparently.

Resolve *nothing* before you have all the necessary data to do so.

Ah, I apologize. I thought you were suggesting that the right gradient representation for interpolation was percentages for stops and pixel values for position and gradient size.

Coming back to the original topic, the WebKit animation pipeline currently interpolates at apply time. As we've discussed it's still possible to make gradient interpolation work correctly with this scheme, although as you've pointed out it is more complicated than just interpolating further down the stack. Unfortunately, making big changes to the pipeline is not something I'm likely to be able to do, and it is anyway something I'm wary about - I don't know the context around why the pipeline is the way it is.

As an implementation detail, it's easier to interpolate stops at the point where WebKit does it if rules (2) and (3) of color-stop fixup are swapped. It seems that:

* swapping these steps merely exchanges one constraint bias for another - i.e. one approach is not more correct than the other
* if you are already interpolating lower down the stack, either approach is of similar complexity
* only poorly specified gradients (i.e. with mixed pixel and percentage values or clear order inversions) are impacted

With this in mind, do you have objections to swapping the two steps?

Cheers,
    -Shane
Shane Stephens 1313470773Tue, 16 Aug 2011 04:59:33 +0000 (UTC)
On Mon, Aug 15, 2011 at 6:45 PM, Brian Manthos wrote:

>  Yes, I object.****
>
> ** **
>
> For the original two reasons:****
>
> **(1)    **It exchanges what I consider as a good rendering for a bad one.
>Fair enough. As I suggested earlier I tend to feel the opposite way. It's a
matter of opinion.> ****
>
> **(2)    **Setting (1) aside for a moment, at best your proposed rendering
> is “as good” as the existing one, which isn’t enough reason to go against
> the inertia/momentum of the spec as it stands (and the degree of
> interoperability of implementations we have thus far).
>This is why it's important to note how marginal the set of impacted
transitions is.

The set of possible animations is different with each approach too. For
example, with my proposed rendering you can queue up a set of stops behind
an occluding stop and have them slide out while maintaining spacing -
something like:

linear-gradient(left, red 50%, black 0%, white, black, white, black, white
40%)
to
linear-gradient(left, red 50%, black 50%, white, black, white, black, white
90%)

In my implementation this generates a pleasant slide-out effect, which is
not possible afaict with the current implementation.

So I don't think it's fair to say my suggestion is at best "as good" without
thinking through the ramifications.> (3)    **It’s a local “fix” for a small portion of the larger problem, and
> as such (a) doesn’t address the whole problem and (b) potentially becomes a
> “tail wagging the dog” precedent for all kinds of other potential changes
> across CSS to support (IMO) “interpolating at the wrong time”.
>I think you misunderstand the intent behind asking for these to be switched.> ****
>(1) it isn't a fix for an insurmountable problem. Supporting both approaches
is possible in WebKit today, it's just *cleaner* to do it the way I'm
proposing.
(2) it doesn't set any precedents, except that when it's possible to
interpolate at either level we should prefer to be able to do it purely at
apply time (Why is this bad, btw? Every other currently animatable property
is interpolatable at apply time)

In particular I am not trying to claim that we should all interpolate at
apply time, in fact I thought that was clear from this discussion. I
completely understand that some properties (e.g. contain and cover) can't be
handled except by resolving them against the current container size, and I
have an approach that will allow me to do so within the current WebKit
framework. It just so happens that I can see an opportunity to make stops
resolution cleaner within the same framework, and can't see any genuine
technical disadvantages.> Also note, in case you missed it, Tab replied [@ Fri 10:57 AM PST] with
> another example that presents a problem for the system you describe.  Unless
> I misunderstood his example.
>You didn't misunderstand his example, but you may have misunderstood my
approach. These examples do not present a problem for the system I
describe.
Cheers,
    -Shane

****>
> ** **
>
> -Brian****
>
> ** **
>
> *From:* Shane Stephens [mailto:]
> *Sent:* Monday, August 15, 2011 6:26 PM
>
> *To:* Brian Manthos
> *Cc:* Tab Atkins Jr.; www-style list
> *Subject:* Re: [css3-images] Order of color-stop fixup****
>
> ** **
>
> On Fri, Aug 12, 2011 at 1:01 PM, Brian Manthos 
> wrote:****
>
> “resolving sizes down to pixel values before interpolation“****
>
> We’re missing each other apparently.****
>
>  ****
>
> Resolve **nothing** before you have all the necessary data to do so.****
>
> ** **
>
> Ah, I apologize. I thought you were suggesting that the right gradient
> representation for interpolation was percentages for stops and pixel values
> for position and gradient size.****
>
> ** **
>
> Coming back to the original topic, the WebKit animation pipeline currently
> interpolates at apply time. As we've discussed it's still possible to make
> gradient interpolation work correctly with this scheme, although as you've
> pointed out it is more complicated than just interpolating further down the
> stack. Unfortunately, making big changes to the pipeline is not something
> I'm likely to be able to do, and it is anyway something I'm wary about - I
> don't know the context around why the pipeline is the way it is.****
>
> ** **
>
> As an implementation detail, it's easier to interpolate stops at the point
> where WebKit does it if rules (2) and (3) of color-stop fixup are swapped.
> It seems that:****
>
> ** **
>
> * swapping these steps merely exchanges one constraint bias for another -
> i.e. one approach is not more correct than the other****
>
> * if you are already interpolating lower down the stack, either approach is
> of similar complexity****
>
> * only poorly specified gradients (i.e. with mixed pixel and percentage
> values or clear order inversions) are impacted****
>
> ** **
>
> With this in mind, do you have objections to swapping the two steps?****
>
> ** **
>
> Cheers,****
>
>     -Shane****
>
Tab Atkins Jr. 1313632114Thu, 18 Aug 2011 01:48:34 +0000 (UTC)
I've discussed the issue more with Shane, and we've managed to find
some cases where the current spec really does produce slightly "bad"
behavior.  Overall, we'd still be OK with leaving the spec how it is,
but would prefer to fix it.

The tl;dr version of the two problems are (1) early fix-up makes
intermediate forms do weird things with fixed-up stops in some
situations, and (2) early fix-up makes it impossible to represent a
decent class of intermediate forms exactly.

The first problem is illustrated at
<http://www.xanthir.com/etc/gradient-fixup-ord...>.  The page
explains the problem, but I'll summarize it here:

In the example, we animate the width of the box from 200px to 1000px,
at the same time as we animate the background from linear-gradient(to
right, red 50%, white 100px, blue 100%) to linear-gradient(to right,
red 10%, white 100px, blue 100%).  (In other words, we only change the
position of the red stop.)

Because the white stop is specified as 100px in both gradients, one
would expect that at all points during the transition the white stop
is either at exactly 100px (when the red stop resolves to less than
100px) or is at the same position as the red stop (when the red stop
resolve to greater than 100px).

However, if you do position-fixup early, as the first gradient on the
page does, you get a weird effect where the white stop jumps *ahead*
of the red stop due to the way the linear interpolation works (the
effect is maximized halfway through the transition, when the red stop
is at 180px and the white is at 200px).

Doing the position-fixup at the last moment instead keeps the white at
a reasonable position the whole time - it's always Math.max(100px,
red.position).


A second problem is in the representation of intermediate values
during a transition.

Many intermediate gradients can be represented exactly.  Some
intrinsically can't (for example, a "to top left" to "to bottom right"
transition, or a "cover" to "contain" transition), and so the
intermediate steps must either be represented in some explicit form
that loses some of the details, or represented as a cross-fade()
function that abstractly represents the gradient at that point in the
transition.

There's a third class that *looks* like they can be exactly
represented, but actually can't be, due to the ordering of the fixup
rules: transitions where the matching color-stops have positions
specified in different unit families (like one in % and the other in
px).  One would naively expect that this could be written as a simple
calc().  For example, say you were transitioning between the following
two gradients:

linear-gradient(to right, red 50%, white 100px, blue 100%)
linear-gradient(to right, red 10%, white 40%, blue 100%)

It *appears* that the 50% point of the transition could be represented as:

linear-gradient(to right, red 30%, white calc(50px + 20%), blue 100%)

This doesn't actually work, though.  If the box's width is 300px, the
naive intermediate form yields:

linear-gradient(to right, red 90px, white 110px, blue 300px)

If you actually resolve the start and end gradients and then
interpolate, though, you get the following:

start: linear-gradient(to right, red 150px, white 150px, blue 300px)
end:   linear-gradient(to right, red 30px, white 120px, blue 300px)
blend: linear-gradient(to right, red 90px, white 135px, blue 300px)

This difference is due to the fact that a color-stop is never
independent; its position is always dependent on the positions of all
preceding color-stops as well.

So, the current rules mean you're required to represent the
intermediate forms with the explicit or cross-fade() forms.  Delaying
the position-fixup instead lets up represent this class of gradients
exactly.  This isn't a bug, just a nice-to-have.

(We could avoid all the issues with "when to do fixup?" if we didn't
fixup at all, and just treated misplaced stops similar to how we
handle stops before 0% on radial-gradient - each stop defines painting
up to its point, but subsequent stops can define themselves earlier
and thus visibly start at a color already partially-blended.  I think
I suggested this at some point early on, and it was rejected because
it would take extra effort to massage the gradient into a form that
the platform libraries liked.)

~TJ
Leif Arne Storset 1313760920Fri, 19 Aug 2011 13:35:20 +0000 (UTC)
Tab Atkins Jr.  skreiv Thu, 18 Aug 2011 03:46:12
+0200

> The first problem is illustrated at
> <http://www.xanthir.com/etc/gradient-fixup-ord...>.  The page
> explains the problem, but I'll summarize it here:
>
> In the example, we animate the width of the box from 200px to 1000px,
> at the same time as we animate the background from linear-gradient(to
> right, red 50%, white 100px, blue 100%) to linear-gradient(to right,
> red 10%, white 100px, blue 100%).  (In other words, we only change the
> position of the red stop.)
>
> Because the white stop is specified as 100px in both gradients, one
> would expect that at all points during the transition the white stop
> is either at exactly 100px (when the red stop resolves to less than
> 100px) or is at the same position as the red stop (when the red stop
> resolve to greater than 100px).
>
> However, if you do position-fixup early, as the first gradient on the
> page does, you get a weird effect where the white stop jumps *ahead*
> of the red stop due to the way the linear interpolation works (the
> effect is maximized halfway through the transition, when the red stop
> is at 180px and the white is at 200px).
>
> Doing the position-fixup at the last moment instead keeps the white at
> a reasonable position the whole time - it's always Math.max(100px,
> red.position).Sorry if I'm being dense, but this doesn't make sense to me. I don't get
why the white stop should at any point be greater than MAX(red stop,  
100px). Where
do you get this from? If I pass the plain gradient, simulating the
transitioning effect now moved to level 4, it gives the expected result in
Chromium, Firefox and Opera (see attachment).

If I attempt a plain CSS transition in Chromium (also attached), it gives  
an effect reminiscent of what you've shown, but only because 'red 10%'  
(which applies immediately due to transitioning gradients not yet being  
supported) is _less than_ 100px for part of the transition (as opposed to  
'white 100px' being more than 100px, which is what I'm getting from you).

Stepping through the code in your script, I see that it's not positioning  
the white stop based on the actual position of the red stop:

(at 50%:)
width       = 600px (50% between 200px and 1000px)
red 50%     = 180px (50% between 50% * 600px = 300px and 10% * 600px =
60px)
white 100px = 200px (50% between MAX(50% * 600px, 100px) and MAX(10% *
600px, 100px), which works out to 50% between 300px and 100px)

It seems that the misplaced white stop comes from interpolating 'red'
between 60px and 300px and interpolating 'white' between 100px and 300px
(seen from the 50% mark). But the rules don't care about red's
hypothetical starting placement at 60px when placing white; they only care
about red's actual current placement at 180px, which is greater than  
white's 100px.

Anyway, this strikes me as a strange way of going about it. With the red  
stop's
position being specified both at the start and the end, why don't you just
transition from 50% to 10%?

In any case, there are no implicitly positioned stops here, so swapping 2
and 3 should not make a difference.

Having said all this, our implementation experience doesn't rule out  
swapping them, but as an implementor of CSS gradients, keeping the order  
(2,3) is preferred, as the code appears to be simpler and more efficient.  
Furthermore, as a web developer and user of CSS gradients, keeping the  
order (2,3) is strongly desired, for the reasons Brian Manthos has  
explained quite thoroughly.
Message missing here (more information)
Tab Atkins Jr. 1313772765Fri, 19 Aug 2011 16:52:45 +0000 (UTC)
On Fri, Aug 19, 2011 at 5:51 AM, Leif Arne Storset  wrote:
> Tab Atkins Jr.  skreiv Thu, 18 Aug 2011 03:46:12
> +0200
>> The first problem is illustrated at
>> <http://www.xanthir.com/etc/gradient-fixup-ord...>.  The page
>> explains the problem, but I'll summarize it here:
>>
>> In the example, we animate the width of the box from 200px to 1000px,
>> at the same time as we animate the background from linear-gradient(to
>> right, red 50%, white 100px, blue 100%) to linear-gradient(to right,
>> red 10%, white 100px, blue 100%).  (In other words, we only change the
>> position of the red stop.)
>>
>> Because the white stop is specified as 100px in both gradients, one
>> would expect that at all points during the transition the white stop
>> is either at exactly 100px (when the red stop resolves to less than
>> 100px) or is at the same position as the red stop (when the red stop
>> resolve to greater than 100px).
>>
>> However, if you do position-fixup early, as the first gradient on the
>> page does, you get a weird effect where the white stop jumps *ahead*
>> of the red stop due to the way the linear interpolation works (the
>> effect is maximized halfway through the transition, when the red stop
>> is at 180px and the white is at 200px).
>>
>> Doing the position-fixup at the last moment instead keeps the white at
>> a reasonable position the whole time - it's always Math.max(100px,
>> red.position).
>
> Sorry if I'm being dense, but this doesn't make sense to me. I don't get
> why the white stop should at any point be greater than MAX(red stop, 100px).
> Where
> do you get this from? If I pass the plain gradient, simulating the
> transitioning effect now moved to level 4, it gives the expected result in
> Chromium, Firefox and Opera (see attachment).
>
> If I attempt a plain CSS transition in Chromium (also attached), it gives an
> effect reminiscent of what you've shown, but only because 'red 10%' (which
> applies immediately due to transitioning gradients not yet being supported)
> is _less than_ 100px for part of the transition (as opposed to 'white 100px'
> being more than 100px, which is what I'm getting from you).Yes, doing a transition currently, where the gradient immediately
jumps to the end state, doesn't illustrate anything useful about this.
 The problem arises when you blend gradients.> Stepping through the code in your script, I see that it's not positioning
> the white stop based on the actual position of the red stop:
>
> (at 50%:)
> width       = 600px (50% between 200px and 1000px)
> red 50%     = 180px (50% between 50% * 600px = 300px and 10% * 600px =
> 60px)
> white 100px = 200px (50% between MAX(50% * 600px, 100px) and MAX(10% *
> 600px, 100px), which works out to 50% between 300px and 100px)
>
> It seems that the misplaced white stop comes from interpolating 'red'
> between 60px and 300px and interpolating 'white' between 100px and 300px
> (seen from the 50% mark). But the rules don't care about red's
> hypothetical starting placement at 60px when placing white; they only care
> about red's actual current placement at 180px, which is greater than white's
> 100px.Incorrect.  The rules, as written, care completely about red's
hypothetical position at the two end points, *because* the rules
currently specify early fix-up.  You *must* first resolve the starting
gradient into absolute lengths (which pushes the white stop out to
300px, when you take into account the box's width at the 50% point),
and do the same for the ending gradient (white stop isn't pushed, so
it's at 100px).  *Then*, after doing so, you're allowed to blend them.> Anyway, this strikes me as a strange way of going about it. With the red
> stop's
> position being specified both at the start and the end, why don't you just
> transition from 50% to 10%?Because the rules don't allow it.  You're arguing that we should do
blending before we do fixup, which is exactly what I'm arguing for as
well.  That gives us the behavior of the second gradient in the
example.  You'll notice that your added gradient has identical
behavior to the second one on the page.> In any case, there are no implicitly positioned stops here, so swapping 2
> and 3 should not make a difference.It does, because you *do* need to resolve implicit stops before you
blend (otherwise, you won't know how to blend).  So, if you push fixup
to after blending, implicit positioning must swap places and occur
before it.  (Alternately, we could mandate two blending rounds, so the
order would be (1) implicitly position first and last stops, (2) blend
what you can, (3) fixup, (4) implicitly position the other stops, (5)
blend the rest.)> Having said all this, our implementation experience doesn't rule out
> swapping them, but as an implementor of CSS gradients, keeping the order
> (2,3) is preferred, as the code appears to be simpler and more efficient.
> Furthermore, as a web developer and user of CSS gradients, keeping the order
> (2,3) is strongly desired, for the reasons Brian Manthos has explained quite
> thoroughly.I'm neutral on the aesthetics - I think both methods have unique
useful visual effects.

~TJ
Message missing here (more information)
Message missing here (more information)
Leif Arne Storset 1314030962Mon, 22 Aug 2011 16:36:02 +0000 (UTC)
Tab Atkins Jr.  skreiv Fri, 19 Aug 2011 18:51:11
+0200

> On Fri, Aug 19, 2011 at 5:51 AM, Leif Arne Storset   
> wrote:
>> Tab Atkins Jr.  skreiv Thu, 18 Aug 2011 03:46:12
>> +0200
>>> The first problem is illustrated at
>>> <http://www.xanthir.com/etc/gradient-fixup-ord...>.  The page
>>> explains the problem, but I'll summarize it here:
>>>
>>> In the example, we animate the width of the box from 200px to 1000px,
>>> at the same time as we animate the background from linear-gradient(to
>>> right, red 50%, white 100px, blue 100%) to linear-gradient(to right,
>>> red 10%, white 100px, blue 100%).  (In other words, we only change the
>>> position of the red stop.)
>>>
>>> Because the white stop is specified as 100px in both gradients, one
>>> would expect that at all points during the transition the white stop
>>> is either at exactly 100px (when the red stop resolves to less than
>>> 100px) or is at the same position as the red stop (when the red stop
>>> resolve to greater than 100px).
>>>
>>> However, if you do position-fixup early, as the first gradient on the
>>> page does, you get a weird effect where the white stop jumps *ahead*
>>> of the red stop due to the way the linear interpolation works (the
>>> effect is maximized halfway through the transition, when the red stop
>>> is at 180px and the white is at 200px).
>>>
>>> Doing the position-fixup at the last moment instead keeps the white at
>>> a reasonable position the whole time - it's always Math.max(100px,
>>> red.position).
>>
>> Sorry if I'm being dense, but this doesn't make sense to me. I don't get
>> why the white stop should at any point be greater than MAX(red stop,  
>> 100px).
>> Where
>> do you get this from? If I pass the plain gradient, simulating the
>> transitioning effect now moved to level 4, it gives the expected result  
>> in
>> Chromium, Firefox and Opera (see attachment).
>>
>> If I attempt a plain CSS transition in Chromium (also attached), it  
>> gives an
>> effect reminiscent of what you've shown, but only because 'red 10%'  
>> (which
>> applies immediately due to transitioning gradients not yet being  
>> supported)
>> is _less than_ 100px for part of the transition (as opposed to 'white  
>> 100px'
>> being more than 100px, which is what I'm getting from you).
>
> Yes, doing a transition currently, where the gradient immediately
> jumps to the end state, doesn't illustrate anything useful about this.
>  The problem arises when you blend gradients.
>
>
>> Stepping through the code in your script, I see that it's not  
>> positioning
>> the white stop based on the actual position of the red stop:
>>
>> (at 50%:)
>> width       = 600px (50% between 200px and 1000px)
>> red 50%     = 180px (50% between 50% * 600px = 300px and 10% * 600px =
>> 60px)
>> white 100px = 200px (50% between MAX(50% * 600px, 100px) and MAX(10% *
>> 600px, 100px), which works out to 50% between 300px and 100px)
>>
>> It seems that the misplaced white stop comes from interpolating 'red'
>> between 60px and 300px and interpolating 'white' between 100px and 300px
>> (seen from the 50% mark). But the rules don't care about red's
>> hypothetical starting placement at 60px when placing white; they only  
>> care
>> about red's actual current placement at 180px, which is greater than  
>> white's
>> 100px.
>
> Incorrect.  The rules, as written, care completely about red's
> hypothetical position at the two end points, *because* the rules
> currently specify early fix-up.  You *must* first resolve the starting
> gradient into absolute lengths (which pushes the white stop out to
> 300px, when you take into account the box's width at the 50% point),
> and do the same for the ending gradient (white stop isn't pushed, so
> it's at 100px).  *Then*, after doing so, you're allowed to blend them.Maybe you're getting a bit ahead of yourself - "the rules, as written"
don't really deal with interpolating percentages in gradients or about
mixing percentages and pixels, yet.

But it would make sense to do it that way. I think I wasn't
familiar enough with transitions to see it, but after working through
Shane's example of 'red 20%, white 20px, blue, black 100%' to 'red 0%,
white 20%, blue 40%, black 100%' it makes sense to me: Transitioning
between % and absolute lengths and between implicit and explicit requires
computation.

It might make sense to do something to prevent the color-stop situation
you mentioned when rebooting this thread. [0]>> Anyway, this strikes me as a strange way of going about it. With the red
>> stop's
>> position being specified both at the start and the end, why don't you  
>> just
>> transition from 50% to 10%?
>
> Because the rules don't allow it.  You're arguing that we should do
> blending before we do fixup, which is exactly what I'm arguing for as
> well.I guess I am.>> In any case, there are no implicitly positioned stops here, so swapping  
>> 2
>> and 3 should not make a difference.
>
> It does, because you *do* need to resolve implicit stops before you
> blend (otherwise, you won't know how to blend).  So, if you push fixup
> to after blending, implicit positioning must swap places and occur
> before it.The point was that the first color stop is the only one without a position
in [1], so step 3 ("If any color-stop still does not have a position")
doesn't come into play. In general, though, I agree that an implicit stop
must be resolved in order to transition to an explicit stop.> (Alternately, we could mandate two blending rounds, so the
> order would be (1) implicitly position first and last stops, (2) blend
> what you can, (3) fixup, (4) implicitly position the other stops, (5)
> blend the rest.)Good thinking. I think I may have been imagining a (more naïve) version of
this all along. Your suggestion could be a good compromise.>> Having said all this, our implementation experience doesn't rule out
>> swapping them, but as an implementor of CSS gradients, keeping the order
>> (2,3) is preferred, as the code appears to be simpler and more  
>> efficient.
>> Furthermore, as a web developer and user of CSS gradients, keeping the  
>> order
>> (2,3) is strongly desired, for the reasons Brian Manthos has explained  
>> quite
>> thoroughly.
>
> I'm neutral on the aesthetics - I think both methods have unique
> useful visual effects.If I understood Brian correctly he wasn't referring primarily to
aesthetics, but to an even distribution of stops, which in my mind is more
about usability and author expectations than aesthetics. Then again,
author expectations will align to any new spec language, so I'll concede
that point.

0. http://lists.w3.org/Archives/Public/www-style...
1. http://www.xanthir.com/etc/gradient-fixup-ord... (which is used as
an illustration in
<http://lists.w3.org/Archives/Public/www-style...>)
Ad
Home | About | Privacy