Skip to content

Commit c03b2ea

Browse files
committed
[css-images-3] Pull in gradient midpoints from L4, per #1284. Also do significant editorial cleanup to match L4's incorportion of the new text, and generally improve things.
1 parent c1e4f53 commit c03b2ea

File tree

1 file changed

+208
-120
lines changed

1 file changed

+208
-120
lines changed

css-images-3/Overview.bs

Lines changed: 208 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ Gradients {#gradients}
174174

175175
A gradient is an image that smoothly fades from one color to another.
176176
These are commonly used for subtle shading in background images, buttons, and many other things.
177-
The gradient notations described in this section allow an author to specify such an image in a terse syntax,
177+
The function">gradient functions described in this section allow an author to specify such an image in a terse syntax,
178178
so that the UA can generate the image automatically when rendering the page.
179179
The syntax of a <> is:
180180

@@ -766,93 +766,236 @@ Repeating Gradients: the ''repeating-linear-gradient()'' and ''repeating-radial-
766766
-->
767767

768768

769-
Gradient Color-Stops {#color-stop-syntax}
770-
-----------------------------------------
769+
Defining Gradient Color {#gradient-colors}
770+
-------------------------
771771

772-
773-
<color-stop-list> = <>#{2,}
774-
<color-stop> = <> <>?
775-
772+
The colors in gradients are specified using color stops
773+
(a <> and a corresponding position on the [=gradient line=])
774+
and color transition hints
775+
(a position between two [=color stops=]
776+
representing the halfway point in the color transition)
777+
which are placed on the gradient line,
778+
defining the color at every point of the line.
779+
(Each [=gradient function=] defines the shape and length of the gradient line,
780+
along with its starting point and ending point;
781+
see above.)
782+
783+

784+
Color Stop Lists
776785

777-
The colors in gradients are specified using color stops.
778-
A color stop is a combination of a color and a position.
779-
782-
While every color stop conceptually has a position,
783-
the position can be omitted in the syntax,
784-
in which case it gets automatically filled in by the user agent;
785-
see below for details.
786-
787-
The color stops for a gradient are specified
786+
787+
Color stops and [=transition hints=] are specified
788788
in a color stop list,
789-
which is a list of two or more color stops,
790-
specified in geometric order.
789+
which is a list of two or more [=color stops=]
790+
interleaved with optional [=transition hints=]:
791791

792-
Color stops are placed on a gradient line,
793-
which defines the colors at every point of a gradient.
794-
The gradient function defines the shape and length of the gradient line,
795-
along with its starting point and ending point.
792+
793+
<color-stop-list> =
794+
<> , [ <>? , <> ]#
795+
<linear-color-stop> = <> && <>?
796+
<linear-color-hint> = <>
797+
796798

797-
Percentages refer to the length of the gradient line
799+
Percentages are resolved against the length of the gradient line
798800
between the starting point and ending point,
799801
with 0% being at the starting point
800802
and 100% being at the ending point.
801803
Lengths are measured along the gradient line
802804
from the starting point
803805
in the direction of the ending point.
804-
808806

809-
Color stops are usually placed between
807+
[=Color stop=] and [=transition hint=] positions
808+
are usually placed between
810809
811810
but that's not required:
812811
the gradient line extends infinitely in both directions,
813-
and a color stop can be placed at any position on the gradient line.
814-
815-
When the position of a color stop is omitted,
816-
it is positioned automatically
817-
halfway between the two surrounding stops.
812+
and positions can be specified anywhere
813+
on the gradient line.
814+
815+
When the position of a [=color stop=] is omitted,
816+
it is automatically assigned a position.
817+
The first or last [=color stop=] in the [=color stop list=]
818+
is assigned
819+
the [=gradient line’s=] [=starting point=] or [=ending point=]
820+
(respectively).
821+
Otherwise,
822+
it's assigned the position halfway between the two surrounding stops.
818823
If multiple stops in a row lack a position,
819-
they space themselves out equally.
820-
821-
The following steps must be applied in order to process the list of color stops.
822-
After applying these rules,
823-
all color stops will have a definite position and color
824-
and they will be in ascending order:
825-
826-
1. If the first color stop does not have a position,
827-
set its position to 0%.
828-
If the last color stop does not have a position,
829-
set its position to 100%.
824+
they space themselves out equally
825+
between the surrounding positioned stops.
826+
See [[#color-stop-fixup]] for details.
830827

831-
2. If a color stop has a position that is less than
832-
the specified position of any color stop before it in the list,
833-
set its position to be equal to the largest specified position of any color stop before it.
834828

835-
3. If any color stop still does not have a position,
836-
then, for each run of adjacent color stops without positions,
837-
set their positions so that they are evenly spaced between the preceding and following color stops with positions.
829+

830+
Coloring the Gradient Line
838831

839832
At each color stop position,
840-
the line is the color of the color stop.
841-
Between two color stops,
842-
the line's color is linearly interpolated between the colors of the two color stops,
843-
with the interpolation taking place in premultiplied RGBA space.
833+
the [=gradient line=] is the color of the color stop.
844834
Before the first color stop,
845-
the line is the color of the first color stop.
846-
After the last color stop, the line is the color of the last color stop.
835+
the [=gradient line=] is the color of the first color stop,
836+
and after the last color stop,
837+
the [=gradient line=] is the color of the last color stop.
838+
Between two color stops,
839+
the [=gradient line’s=] color is interpolated between the colors of the two color stops,
840+
with the interpolation taking place in premultiplied RGBA space.
841+
842+
By default,
843+
this interpolation is linear--
844+
at 25%, 50%, or 75% of the distance between two color stops,
845+
the color is a 25%, 50%, or 75% blend of the colors of the two stops.
846+
847+
However, if a [=transition hint=] was provided between two color stops,
848+
the interpolation is non-linear,
849+
and controlled by the hint:
850+
851+
852+
    853+
  1. 854+
    Determine the location of the [=transition hint=] as a percentage of the distance between the two color stops,
    855+
    denoted as a number between 0 and 1,
    856+
    where 0 indicates the hint is placed right on the first color stop,
    857+
    and 1 indicates the hint is placed right on the second color stop.
    858+
    Let this percentage be H.
    859+
    860+
  2. 861+
    For any given point between the two color stops,
    862+
    determine the point's location as a percentage of the distance between the two color stops,
    863+
    in the same way as the previous step.
    864+
    Let this percentage be P.
    865+
    866+
  3. 867+
    Let C, the color weighting at that point,
    868+
    be equal to PlogH(.5).
    869+
    870+
  4. 871+
    The color at that point is then a linear blend between the colors of the two color stops,
    872+
    blending (1 - C) of the first stop and C of the second stop.
    873+
    874+
    875+
    876+
    Note: The [=transition hint=] specifies where the “halfway color”--
    877+
    the 50% blend between the colors of the two surrounding color stops--
    878+
    should be placed.
    879+
    When the hint is exactly halfway between the two surrounding color stops,
    880+
    the above interpolation algorithm
    881+
    happens to produce the ordinary linear interpolation.
    882+
    If the hint is placed anywhere else,
    883+
    it produces a smooth exponential curve
    884+
    between the surrounding color stops,
    885+
    with the “halfway color” occuring exactly where the hint specifies.
    886+
    887+
    Issue: Add a visual example of a color hint being used.
    847888

    848889
    If multiple color stops have the same position,
    849-
    they produce an infinitesimal transition from the one specified first in the rule
    890+
    they produce an infinitesimal transition from the one specified first in the list
    850891
    to the one specified last.
    851892
    In effect, the color suddenly changes at that position rather than smoothly transitioning.
    852893

    894+
    895+
    What does “pre-multiplied” mean?
    896+
    897+
    A “pre-multiplied” color
    898+
    is written in a form
    899+
    where the alpha channel
    900+
    is multiplied into the color channels,
    901+
    rather than being processed independently.
    902+
    For example, a partially-transparent blue may be given as rgba(0, 0, 255, .5),
    903+
    which would then be expressed as [0, 0, 127.5, .5] in its premultiplied representation.
    904+
    905+
    Interpolating colors using the premultiplied representations
    906+
    rather than the plain rgba representations
    907+
    tends to produce more attractive transitions,
    908+
    particularly when transitioning from a fully opaque color to fully transparent.
    909+
    910+
    Note that transitions where either the transparency or the color are held constant
    911+
    (for example, transitioning between rgba(255, 0, 0, 100%) (opaque red)
    912+
    and rgba(0,0,255,100%) (opaque blue),
    913+
    or rgba(255,0,0,100%) (opaque red)
    914+
    and rgba(255,0,0,0%) (transparent red))
    915+
    have identical results whether the color interpolation is done in premultiplied or non-premultiplied color-space.
    916+
    Differences only arise when both the color and transparency differ between the two endpoints.
    917+
    918+
    919+
    The following example illustrates the difference between
    920+
    a gradient transitioning in pre-multiplied sRGBA
    921+
    and one transitioning (incorrectly) in non-premultiplied.
    922+
    In both of these example,
    923+
    the gradient is drawn over a white background.
    924+
    Both gradients could be written with the following value:
    925+
    926+
    linear-gradient(90deg, red, transparent, blue)
    927+
    928+
    With premultiplied colors,
    929+
    transitions to or from "transparent" always look nice:
    930+
    931+
    (Image requires SVG)
    932+
    933+
    On the other hand,
    934+
    if a gradient were to incorrectly transition in non-premultiplied space,
    935+
    the center of the gradient would be a noticeably grayish color,
    936+
    because "transparent" is actually a shorthand for ''rgba(0,0,0,0)'', or transparent black,
    937+
    meaning that the red transitions to a black
    938+
    as it loses opacity,
    939+
    and similarly with the blue's transition:
    940+
    941+
    (Image requires SVG)
    942+
    943+
    944+
    945+
    946+
    947+
    948+

    949+
    Color Stop “Fixup”
    950+
    951+
    When resolving the [=used value|used=] positions of each [=color stop=],
    952+
    the following steps must be applied in order:
    953+
    954+
      955+
    1. 956+
      If the first color stop does not have a position,
      957+
      set its position to 0%.
      958+
      If the last color stop does not have a position,
      959+
      set its position to 100%.
      960+
      961+
    2. 962+
      If a color stop or [=transition hint=] has a position
      963+
      that is less than the specified position
      964+
      of any color stop or [=transition hint=] before it in the list,
      965+
      set its position to be equal to the largest specified position
      966+
      of any color stop or [=transition hint=] before it.
      967+
      968+
    3. 969+
      If any color stop still does not have a position,
      970+
      then, for each run of adjacent color stops without positions,
      971+
      set their positions so that they are evenly spaced
      972+
      between the preceding and following color stops with positions.
      973+
      974+
      975+
      After applying these rules,
      976+
      all [=color stops=] and [=transition hints=] will have a definite position and color
      977+
      and they will be in ascending order.
      978+
      979+
      Note: It is recommended that authors exercise caution
      980+
      when mixing different types of units,
      981+
      such as px, em, or %,
      982+
      as this can cause a color stop to unintentionally try to move before an earlier one.
      983+
      For example,
      984+
      the rule ''background-image: linear-gradient(yellow 100px, blue 50%)''
      985+
      wouldn't trigger any fix-up while the background area is at least ''200px'' tall.
      986+
      If it was ''150px'' tall, however,
      987+
      the blue color stop's position would be equivalent to ''75px'',
      988+
      which precedes the yellow color stop,
      989+
      and would be corrected to a position of ''100px''.
      990+
      Additionally, since the relative ordering of such color stops
      991+
      cannot be determined without performing layout,
      992+
      they will not interpolate smoothly in
      993+
      994+
      995+
      853996
      854997
      Below are several pairs of gradients.
      855-
      The latter of each pair is a manually "fixed-up" version of the former,
      998+
      The latter of each pair is a manually fixed-up version of the former,
      856999
      obtained by applying the above rules.
      8571000
      For each pair, both gradients will render identically.
      8581001
      The numbers in each arrow specify which fixup steps are invoked in the transformation.
      @@ -863,86 +1006,31 @@ Gradient Color-Stops {#color-stop-syntax}
      8631006
      linear-gradient(red 0%, white 20%, blue 100%)
      8641007

      8651008
      2. linear-gradient(red 40%, white, black, blue)
      866-
      =13=>
      1009+
      =1,3=>
      8671010
      linear-gradient(red 40%, white 60%, black 80%, blue 100%)
      8681011

      8691012
      3. linear-gradient(red -50%, white, blue)
      870-
      =13=>
      1013+
      =1,3=>
      8711014
      linear-gradient(red -50%, white 25%, blue 100%)
      8721015

      8731016
      4. linear-gradient(red -50px, white, blue)
      874-
      =13=>
      1017+
      =1,3=>
      8751018
      linear-gradient(red -50px, white calc(-25px + 50%), blue 100%)
      8761019

      8771020
      5. linear-gradient(red 20px, white 0px, blue 40px)
      8781021
      =2=>
      8791022
      linear-gradient(red 20px, white 20px, blue 40px)
      8801023

      8811024
      6. linear-gradient(red, white -50%, black 150%, blue)
      882-
      =12=>
      1025+
      =1,2=>
      8831026
      linear-gradient(red 0%, white 0%, black 150%, blue 150%)
      8841027

      8851028
      7. linear-gradient(red 80px, white 0px, black, blue 100px)
      886-
      =23=>
      1029+
      =2,3=>
      8871030
      linear-gradient(red 80px, white 80px, black 90px, blue 100px)
      8881031
      8891032
      8901033

      891-
      892-
      The following example illustrates the difference between
      893-
      a gradient transitioning in pre-multiplied sRGBA
      894-
      and one transitioning (incorrectly) in non-premultiplied.
      895-
      In both of these example,
      896-
      the gradient is drawn over a white background.
      897-
      Both gradients could be written with the following value:
      898-
      899-
      linear-gradient(90deg, red, transparent, blue)
      900-
      901-
      In premultiplied space,
      902-
      transitions to or from "transparent" always look nice:
      903-
      904-
      (Image requires SVG)
      905-
      906-
      On the other hand,
      907-
      if a gradient were to incorrectly transition in non-premultiplied space,
      908-
      the colors near "transparent" would noticeably darken to a grayish color,
      909-
      because "transparent" is actually a shorthand for ''rgba(0,0,0,0)'', or transparent black:
      910-
      911-
      (Image requires SVG)
      912-
      913-
      914-
      Note: It is recommended that authors not mix different types of units,
      915-
      such as px, em, or %,
      916-
      in a single rule,
      917-
      as this can cause a color stop to unintentionally try to move before an earlier one.
      918-
      For example, the rule ''background-image: linear-gradient(yellow 100px, blue 50%)''
      919-
      wouldn't require any fix-up as long as the background area is at least 200px tall.
      920-
      If it was 150px tall, however,
      921-
      the blue color stop's position would be equivalent to "75px",
      922-
      which precedes the yellow color stop,
      923-
      and would be corrected to a position of 100px.
      924-
      Additionally, since the relative ordering of such color stops
      925-
      cannot be determined without performing layout,
      926-
      they will not interpolate smoothly in
      927-
      928-
      929-
      930-
      Note: The definition and implications of "premultiplied" color spaces are given elsewhere in the technical literature,
      931-
      but a quick primer is given here to illuminate the process.
      932-
      Given a color expressed as an rgba() 4-tuple,
      933-
      one can convert this to a premultiplied representation
      934-
      by multiplying the red, green, and blue components by the alpha component.
      935-
      For example, a partially-transparent blue may be given as rgba(0,0,255,.5),
      936-
      which would then be expressed as [0, 0, 127.5, .5] in its premultiplied representation.
      937-
      Interpolating colors using the premultiplied representations
      938-
      rather than the plain rgba representations
      939-
      tends to produce more attractive transitions,
      940-
      particularly when transitioning from a fully opaque color to fully transparent.
      941-
      Note that transitions where either the transparency or the color are held constant
      942-
      (for example, transitioning between rgba(255,0,0,100%) and rgba(0,0,255,100%),
      943-
      or rgba(255,0,0,100%) and rgba(255,0,0,0%))
      944-
      have identical results whether the color interpolation is done in premultiplied or non-premultiplied color-space.
      945-
      Differences only arise when both the color and transparency differ between the two endpoints.
      9461034

      9471035

      9481036
      commit comments
      Comments
       (0)