[css3-images] Gradients feedback

tl;dr: I've added instructions for serializing gradients.  I want to
add an ending-point argument to linear-gradient(), and change the
color transitions to happen in pre-multiplied rgba space.

Simon and I recently had a twitter conversation about issues keeping
him from wanting to implement the draft gradient syntax in Webkit.

One of the issues was that gradients didn't have a defined
serialization.  I've now defined this in the draft.

Another issue was that linear-gradient() had too much "magic".  There
is explicitly different behavior for all four combinations of
specified and omitted values in the first argument.  He'd prefer that
the syntax have more regular behavior, such that a missing value is
just filled in with a default value.  He sent an email to this effect
back during the original syntax discussions:

After thinking it through, I believe his complaint is valid, though I
strongly disagree with the fix he proposes in that email.  Instead,
I'd like to add an additional argument to the linear-gradient() syntax
- another <bg-position> given as the second argument to the function,
for specifying an ending-point for the gradient.

Let me explain why I think this addresses his complaint adequately.

Right now, there are four cases that can be expressed by the first
argument to linear-gradient() - the <bg-position> can be present or
absent, and the <angle> can be present or absent.  These are all
handled somewhat specially, in what appears to be an ad hoc manner.
Really, though, the cases are very consistent and in-line with the
"unspecified values just take a default" ethos that Simon wants;
however, this isn't apparent with only four cases to look at.  Adding
an ending-point argument makes this much more apparent, and also
addresses several use-cases.

In his email, Simon notes that it appears that linear-gradient() is
actually expressing two or three different syntaxes.  He's right -
there are two substantially different behaviors here, keyed by the
presence or absence of the angle.

If the angle is absent, the gradient-line simply goes from one point
to another point.  If both points are specified, you're done.  If the
ending-point is missing, it defaults to rotating the starting-point
around the center of the box.  If the starting-point is missing, it
defaults to "top center".

If the angle is present, the gradient-line starts at the
starting-point, extends outward at the angle specified, and ends when
a line drawn perpendicular to the gradient-line would intersect with
the ending-point.  If both points are specified, you're done.  If the
ending-point is missing, it defaults to the corner of the box in the
direction of the angle.  If the starting-point is missing, it default
to the corner of the box in the opposite direction of the angle.

In either case, missing points have consistent, well-defined default
values.  The defaults are just completely different between the two
cases.  I believe this is necessary to make the two cases actually be
useful.  Simon's proposal for always defaulting the starting-point to
the top-left is insufficient for either case.  If the angle is absent,
it makes the default behavior a diagonal gradient, when the most
common gradients on the web and elsewhere are vertical and horizontal.
 If the angle is present, it makes the only useful angle values be
between 0deg and -90deg - 0deg to 90deg and 180deg to 270deg have
unintuitive results, while 90deg to 180deg appears to have no effect
at all in most cases (it draws the gradient completely outside of the
box unless there are color-stops with positions lower than 0%).

I believe that the current level of "smarts" used in differentiating
the defaults of the two cases is the minimum necessary to make the
syntax useful.  The benefits of simplifying it further would be
strongly outweighed by the downsides of the bad defaults, in my

Additional feedback comes from David Baron, in the Mozilla bug at
https://bugzilla.mozilla.org/show_bug.cgi?id=591600 .  He wants the
colors in gradients to be transitioned in pre-multiplied space.  This
is because, currently, transitions to and from 'transparent' look ugly
- going yellow->transparent produces a visibly grayish area in the
middle because the color is going from yellow->black while the opacity
goes from 100%->0%.  This will still be the case in premultiplied
space because 'transparent' is *defined* to be 'rgba(0,0,0,0)', but if
you're using premultiplied colors you can do a
yellow->rgba(255,255,0,0) transition to get an attractive transition
that stays visibly yellow the entire time.

I've already made this change in the draft, but let me know if there's
any problems with it.


Received on Sunday, 29 August 2010 17:01:45 UTC