Skip to content

Commit 1f940c6

Browse files
committed
[css-images-4] Add <color-interpolation-method> to all gradient functions, closes #6667 #6094
Also moved premultiplied section to css-color-4.
1 parent abbef9b commit 1f940c6

File tree

4 files changed

+78
-58
lines changed

4 files changed

+78
-58
lines changed

css-color-4/Overview.bs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5057,6 +5057,58 @@ Interpolating with alpha</h3>
50575057
each component which had been premultiplied
50585058
is divided by the interpolated alpha value.
50595059
5060+
<details class=note id=premultiplied>
5061+
<summary>Why is premultiplied alpha useful?</summary>
5062+
5063+
<!-- A “pre-multiplied” color
5064+
is written in a form
5065+
where the alpha channel
5066+
is multiplied into the color channels,
5067+
rather than being processed independently.
5068+
For example, a partially-transparent blue may be given as <code class=lang-css><nobr>rgba(0, 0, 255, .5)</nobr></code>,
5069+
which would then be expressed as <code><nobr>[0, 0, 127.5, .5]</nobr></code> in its premultiplied representation. -->
5070+
5071+
Interpolating colors using the premultiplied representations
5072+
tends to produce more attractive transitions than the non-premultiplied representations,
5073+
particularly when transitioning from a fully opaque color to fully transparent.
5074+
5075+
Note that transitions where either the transparency or the color are held constant
5076+
(for example, transitioning between <code class=lang-css><nobr>rgba(255, 0, 0, 100%)</nobr></code> (opaque red)
5077+
and <code class=lang-css><nobr>rgba(0,0,255,100%)</nobr></code> (opaque blue),
5078+
or <code class=lang-css><nobr>rgba(255,0,0,100%)</nobr></code> (opaque red)
5079+
and <code class=lang-css><nobr>rgba(255,0,0,0%)</nobr></code> (transparent red))
5080+
have identical results whether the color interpolation is done in premultiplied or non-premultiplied color-space.
5081+
Differences only arise when <em>both</em> the color and transparency differ between the two endpoints.
5082+
5083+
<div class=example>
5084+
The following example illustrates the difference between
5085+
a gradient transitioning via pre-multiplied values
5086+
(in this case sRGB, since all colors involved are legacy colors)
5087+
and one transitioning (incorrectly) via non-premultiplied values.
5088+
In both of these examples,
5089+
the gradient is drawn over a white background.
5090+
Both gradients could be written with the following value:
5091+
5092+
<pre>linear-gradient(90deg, red, transparent, blue)</pre>
5093+
5094+
With premultiplied colors,
5095+
transitions to or from "transparent" always look nice:
5096+
5097+
<object data="images/gradient2.svg" width="200" height="100">(Image requires SVG)</object>
5098+
5099+
On the other hand,
5100+
if a gradient were to incorrectly transition in non-premultiplied space,
5101+
the center of the gradient would be a noticeably grayish color,
5102+
because "transparent" is actually a shorthand for ''rgba(0,0,0,0)'', or transparent black,
5103+
meaning that the red transitions to a black
5104+
as it loses opacity,
5105+
and similarly with the blue's transition:
5106+
5107+
<object data="images/gradient3.svg" width="200" height="100">(Image requires SVG)</object>
5108+
</div>
5109+
5110+
</details>
5111+
50605112
<div class="example" id="ex-premultiplied-srgb">
50615113
For example, to interpolate, in the sRGB color space, the two sRGB colors
50625114
<span class="swatch" style="--color: rgb(24%, 12%, 98%, 0.4)"></span> rgb(24% 12% 98% / 0.4)

css-images-4/Overview.bs

Lines changed: 26 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Default Highlight: css
2323
</pre>
2424

2525
<pre class=link-defaults>
26+
spec: css-color-4; type: type; text: <color-interpolation-method>
2627
spec: css-images-3;
2728
type: function;
2829
text: image-set();
@@ -1181,7 +1182,16 @@ Gradients</h2>
11811182
Linear Gradients: the ''linear-gradient()'' notation {#linear-gradients}
11821183
------------------------------------------------------------------------
11831184

1184-
Note: No change from [[css3-images]].
1185+
Compared to [[css3-images]], this level adds a <<color-interpolation-method>> token
1186+
to customize color interpolation in gradients as described in [[css-color-4#interpolation]].
1187+
1188+
<pre class=prod>
1189+
<dfn>linear-gradient()</dfn> = linear-gradient(
1190+
[ <<angle>> | to <<side-or-corner>> ]? || <<color-interpolation-method>>,
1191+
<<color-stop-list>>
1192+
)
1193+
<dfn>&lt;side-or-corner></dfn> = [left | right] || [top | bottom]
1194+
</pre>
11851195

11861196
<!--
11871197
████████ ███ ████████ ████ ███ ██
@@ -1197,7 +1207,15 @@ Note: No change from [[css3-images]].
11971207
Radial Gradients: the ''radial-gradient()'' notation {#radial-gradients}
11981208
------------------------------------------------------------------------
11991209

1200-
Note: No change from [[css3-images]].
1210+
Compared to [[css3-images]], this level adds a <<color-interpolation-method>> token
1211+
to customize color interpolation in gradients as described in [[css-color-4#interpolation]].
1212+
1213+
<pre class=prod>
1214+
<dfn>radial-gradient()</dfn> = radial-gradient(
1215+
[[ <<ending-shape>> || <<size>> ]? [ at <<position>> ]? ] || <<color-interpolation-method>>,
1216+
<<color-stop-list>>
1217+
)
1218+
</pre>
12011219

12021220
<!--
12031221
██████ ███████ ██ ██ ████ ██████
@@ -1250,7 +1268,7 @@ Conic Gradients: the ''conic-gradient()'' notation</h3>
12501268

12511269
<pre class='prod'>
12521270
<dfn>conic-gradient()</dfn> = conic-gradient(
1253-
[ from <<angle>> ]? [ at <<position>> ]?,
1271+
[ [ from <<angle>> ]? [ at <<position>> ]? ] || <<color-interpolation-method>>,
12541272
<<angular-color-stop-list>>
12551273
)
12561274
</pre>
@@ -1570,7 +1588,11 @@ Coloring the Gradient Line</h4>
15701588
the [=gradient line=] is the color of the last <a>color stop</a>.
15711589
Between two <a>color stops</a>,
15721590
the [=gradient line’s=] color is interpolated between the colors of the two <a>color stops</a>,
1573-
with the interpolation taking place in <a href="#premultiplied">premultiplied RGBA space</a>.
1591+
with the interpolation taking place in the specified color space,
1592+
using premultiplied alpha, as defined in [[css-color-4#interpolation-alpha]].
1593+
If no <<color-interpolation-method>> is specified in the gradient function,
1594+
the color space used for gradient interpolation
1595+
is the default interpolation color space as defined in [[css-color-4]].
15741596

15751597
By default,
15761598
this interpolation is linear--
@@ -1624,60 +1646,6 @@ Coloring the Gradient Line</h4>
16241646
to the one specified last.
16251647
In effect, the color suddenly changes at that position rather than smoothly transitioning.
16261648

1627-
<details class=note id=premultiplied>
1628-
<summary>What does “pre-multiplied” mean?</summary>
1629-
1630-
A “pre-multiplied” color
1631-
is written in a form
1632-
where the alpha channel
1633-
is multiplied into the color channels,
1634-
rather than being processed independently.
1635-
For example, a partially-transparent blue may be given as <code class=lang-css><nobr>rgba(0, 0, 255, .5)</nobr></code>,
1636-
which would then be expressed as <code><nobr>[0, 0, 127.5, .5]</nobr></code> in its premultiplied representation.
1637-
1638-
Interpolating colors using the premultiplied representations
1639-
rather than the plain rgba representations
1640-
tends to produce more attractive transitions,
1641-
particularly when transitioning from a fully opaque color to fully transparent.
1642-
1643-
Note that transitions where either the transparency or the color are held constant
1644-
(for example, transitioning between <code class=lang-css><nobr>rgba(255, 0, 0, 100%)</nobr></code> (opaque red)
1645-
and <code class=lang-css><nobr>rgba(0,0,255,100%)</nobr></code> (opaque blue),
1646-
or <code class=lang-css><nobr>rgba(255,0,0,100%)</nobr></code> (opaque red)
1647-
and <code class=lang-css><nobr>rgba(255,0,0,0%)</nobr></code> (transparent red))
1648-
have identical results whether the color interpolation is done in premultiplied or non-premultiplied color-space.
1649-
Differences only arise when <em>both</em> the color and transparency differ between the two endpoints.
1650-
1651-
<div class=example>
1652-
The following example illustrates the difference between
1653-
a gradient transitioning in pre-multiplied sRGBA
1654-
and one transitioning (incorrectly) in non-premultiplied.
1655-
In both of these example,
1656-
the gradient is drawn over a white background.
1657-
Both gradients could be written with the following value:
1658-
1659-
<pre>linear-gradient(90deg, red, transparent, blue)</pre>
1660-
1661-
With premultiplied colors,
1662-
transitions to or from "transparent" always look nice:
1663-
1664-
<object data="images/gradient2.svg" width="200"height="100">(Image requires SVG)</object>
1665-
1666-
On the other hand,
1667-
if a gradient were to incorrectly transition in non-premultiplied space,
1668-
the center of the gradient would be a noticeably grayish color,
1669-
because "transparent" is actually a shorthand for ''rgba(0,0,0,0)'', or transparent black,
1670-
meaning that the red transitions to a black
1671-
as it loses opacity,
1672-
and similarly with the blue's transition:
1673-
1674-
<object data="images/gradient3.svg" width="200"height="100">(Image requires SVG)</object>
1675-
</div>
1676-
1677-
</details>
1678-
1679-
1680-
16811649
<h4 id=color-stop-fixup>
16821650
Color Stop “Fixup”</h4>
16831651

0 commit comments

Comments
 (0)