W3C home > Mailing lists > Public > www-style@w3.org > August 2009

Re: Gradient syntax proposal

From: Tab Atkins Jr. <jackalmage@gmail.com>
Date: Thu, 20 Aug 2009 09:01:18 -0500
Message-ID: <dd0fbad0908200701j59226614q54ee6e1dd999954d@mail.gmail.com>
To: David Perrell <davidp@hpaa.com>
Cc: www-style@w3.org
On Thu, Aug 20, 2009 at 12:47 AM, David Perrell<davidp@hpaa.com> wrote:
> Tab Atkins Jr. wrote:
> | In the 100px case there is a noticeable difference, though probably
> | not a *significant* difference - even in the one that preserves the
> | gradient, it's dropped to a very short, sharp one spanning a mere 5
> | pixels.  In either case, the 30px green sides, which are presumably
> | meant to be have padding overlaid on them to keep content out, are
> | causing a problem all by themselves, independent of the gradient
> | fades.  You should probably have a min-width placed on the box to
> | prevent it from ever getting that small in the first place, or specify
> | the green sides in % as well.
> The 5-pixel span is still a soft edge, and the width of the green is equal on both sides. The one with % measures on the full width has mismatched sides. A hard transition and mismatched sides could occur while the wheat-color center is wide enough for text and/or an image. I made the initial image narrow in order to use two columns.

Ah, I didn't notice the significance of the mismatched sides on the
left example.  I assumed you just made a mistake in creating it.

That is produced by a wider issue, though, because the same thing
would happen with absolute lengths.  Previous color-stops trump later
color-stops when they fight for position *in general*.  The only way
around that would be some way of specifying that, past a certain
point, the later stops should trump earlier stops.

I don't think we need a general solution for this; I believe that in
virtually all instances this will be about exactly the situation you
see in your example, where you have a symmetrical gradient that you
want to keep that way.  I see an opportunity here to let us simplify
this common case while addressing the problem.

Just like how you can specify a single starting point and it will
automatically infer the ending point on the opposite side for you
(allowing you to write "left" instead of the full "left to right"),
you should be able to specify half of your color-stops and let the
system infer the other half.  When employing this, you must only
specify color stops up to 50% - anything larger than that (whether
purposely, like 65%, or accidentally, like 100px in a 150px box)
automatically gets dropped back to 50%.  The system will then
automatically fill in stops for the other half in reverse order, using
the used values of the original stops and measuring from the end.

I'm not sure what a good syntax for this is, but the first thing that
comes to mind is this:

linear-gradient(left / green 30px, wheat 20%, mirror)

Which translates roughly into:

linear-gradient(left / green 30px, wheat 20%, wheat 80%, green
calc(100% - 30px))

But in your 100px example, would instead translate to roughly:

linear-gradient(left / green 30px, wheat 30px, wheat calc(100% -
30px), green calc(100% - 30px))

Because the used value of the first wheat color-stop got pushed to
30px by the green stop.  This prevents the later asymmetrical conflict
where the wheat stop sits at 80% and shoves the green stop out of the

(And yes, Brad, I considered your proposed syntax for this as well.  I
still find the use of the / there confusing, and think it would be
*even worse* if it changed the precedence rules as well.  Add in the
"don't specify anything past 50%" bit, and I think it becomes
unworkable for this.)

Thoughts?  Better syntax ideas?

> On one hand, the gradient on the right does degrade better. On the other, lengths are relative to the gradient - so why should percentages be different?


> Actually, neither color-stop positioning solution is satisfactory inasmuch as the implicit position of color-stops (subdividing the span between explicit color stops) doesn't jibe with either. A default value is normally one of several specifiable options.

Not sure what you're saying here.

> That brings up another possibility: Each color-stop position type (percent, relative length, pixels) has its own reference span. So long as all color stops use the same position type, they are all relative to the length of the gradient. But when a color-stop position type differs from the previous, the previous stop is the start position for subsequent stops until the color-stop position type changes again. If the color-stop position type changes back to a previous type, the previous type's start reference point is restored (and it becomes an end reference point if relevant).
> So, for this gradient:
> left / blue, red 20%, yellow 2em, green 4em, teal 6px, blue 80%;
> red->blue gradient is from 0-20% total width. red->yellow is from 20% to (20%+2em), yellow->green is from (20%+2em) to (20%+4em), green->teal is from (20%+4em) to (20%+4em+6px), teal->blue is from (20%+4em+6px) to 80%, and solid blue is from 80%-100%;
> There, that's pretty simple, right? :-)

Uh, right!  ^_^

While interesting, and perhaps useful, this sort of processing seems
*way* too complex.  Just use SVG.  ^_^

> | Also, the WG talked not long ago about the introduction of the max()
> | and min() functions, which would help in situations like these.  You
> | could specify the wheat stop as "wheat max(20%, 50px)", ensuring that
> | the green->wheat transition remains *at least* 20px wide.  Specifying
> | the far stop is a bit more complicated, unfortunately - "wheat
> | min(80%, calc(100% - 50px))" or "wheat calc(100% - max(20%, 50px))".
> I seem to recall that suggestion but couldn't find the origin in the archives. Since it isn't in the Values and Units module, it will not be of much help.

Last I saw it, it was discussed on a telecon and appeared in the
minutes.  Here you go:


Google is *way* better at searching the archives than the archive
search is.  Just use a
site:http://lists.w3.org/Archives/Public/www-style/ specifier on your

Received on Thursday, 20 August 2009 14:03:00 UTC

This archive was generated by hypermail 2.4.0 : Monday, 23 January 2023 02:13:39 UTC