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 10:42:32 -0500
Message-ID: <dd0fbad0908200842i57bd3590m2507b183f0113e43@mail.gmail.com>
To: James Elmore <James.Elmore@cox.net>
Cc: CSS <www-style@w3.org>
On Thu, Aug 20, 2009 at 9:53 AM, James Elmore<James.Elmore@cox.net> wrote:
> On Aug 20, 2009, at 7:01 AM, Tab Atkins Jr. wrote:
>> 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
>> way.
>
> Sorry for quoting the entire message, but my brain can't find good places to
> clip, yet today.

No problem.  Clipped for you.  ^_^

> Could we allow the designer / user to specify a reference point within the
> gradient? I mean, if you want everything centered, specify the gradient line
> in the middle of the element, then tell CSS that everything is offset from
> the center of the gradient line.

Hmm.  That's another interesting idea.

> This is just a suggestion, and I can't imagine what a 'good' syntax would
> look like, but imagine if I wanted my gradient centered, I might write:
>
> linear-gradient(left 15px to right 15px / 50% / grey -40%, tan, grey +40%)
>
> (I know, dumb example.) This would mean the gradient line runs left to right
> in the center of the block, offset 15px from each edge. The color offsets
> are from the 50% point of the gradient line, with grey on both left and
> right edges as 10% of the gradient (50% +/- 40%), and the tan in the middle.

Side note: your gradient isn't offset 15px from each edge.  Since this
uses bg-position syntax, you're just placing a point at (0,15px) and
one at (100%, 15px), that is, making an ordinary left to right
gradient.  To get the edge offset you'd do "left 15px center" (the
other point can be inferred).  Alternately, "15px center" or "15px
50%".

Translating the example provided by David, you'd have:

linear-gradient(30px center / 50% / green -50%, wheat -30%, wheat 30%,
green 50%)

Of course, this particular case can actually be reproduced well in the
current syntax (I just didn't think of it earlier):

linear-gradient(30px center / green, wheat 20%, wheat 80%, green)

This relies on the fact that the fixed-width part of David's example
is a solid color.  Let's assume instead that it's a gradient as well,
e.g.:

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

Your proposal would make this:

linear-gradient(left / 50% / darkgreen -50%, green calc(-50% + 30px),
wheat -30%, wheat 30%, green calc(50% - 30px), darkgreen 50%)

This, um, doesn't seem simpler at all.  It's actually quite a bit more
difficult to follow.  It also doesn't solve the asymmetry problem that
plagued David's example, where on the left the green stop pushes the
wheat stop over, but on the right the wheat stop pushes the green stop
over.

In my proposed syntax, this would be:

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

This seems to be really simple, doesn't require a lick of calc()
(which is what Brad hated to see all over the place), and solves the
asymmetry problem.

The downside of 'mirror' (or whatever syntax it ends up with) is that
it favors the 50% point.  Your proposal allows one to base things off
of any location, which might make some situations easier.  I'm not
sure what these situations might be, though, and the syntax ends up
complexifying things enough that I'd want some pretty good
justification before I integrated it.

> Yes, this can be done with calc(), and probably other ways as well. But if
> the user is thinking in terms of centering, would it not be more
> brain-friendly to allow everything to offset from the center?

Possibly; I didn't see any savings in your example or David's example,
but it's possible that it does make things simpler in some cases.

> And, if the user has a menu, say 20em wide on the left edge, he/she could
> specify offsets from the menu edge as:
>
> linear-gradient(left to right / 20em / wheat -20em, red, white, blue)
>
> This would place the wheat on the left, starting at the left border (end of
> the gradient, up to the zero point (now 20 px offset from the end), where
> the red, white, and blue would start.

Not quite.  ^_^  The red wouldn't default to 0%, because it's not the
first stop.  The blue would still default to 100%, and then red and
white would be distributed evenly between -20em and 100%.  Let's
assume that you have "red 0" instead.

Isn't it just as easy to specify that as:

linear-gradient(20em 0 to 100% 0 / wheat -20em, red 0, white, blue)

?

> Again, sorry for not clipping, but I wanted to capture the idea. Maybe I can
> present it more clearly later, when I actually wake up.

Heh, ok.  So far I'm not seeing anything that can't be handled as
easily in the current syntax, and more easily with some sort of
'mirror' syntax, but I'm open to examples that show otherwise.

~TJ
Received on Thursday, 20 August 2009 15:43:34 GMT

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