Skip to content

Commit 2f0d0da

Browse files
authoredSep 13, 2024··
Merge pull request #2341 from sass/feature.color-4
Merge feature.color-4 into main
2 parents 4fa5a02 + de181d9 commit 2f0d0da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+6069
-1122
lines changed
 

‎CHANGELOG.md

+188
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,199 @@
11
## 1.79.0
22

3+
* **Breaking change**: Passing a number with unit `%` to the `$alpha` parameter
4+
of `color.change()`, `color.adjust()`, `change-color()`, and `adjust-color()`
5+
is now interpreted as a percentage, instead of ignoring the unit. For example,
6+
`color.change(red, $alpha: 50%)` now returns `rgb(255 0 0 / 0.5)`.
7+
8+
* **Potentially breaking compatibility fix**: Sass no longer rounds RGB channels
9+
to the nearest integer. This means that, for example, `rgb(0 0 1) != rgb(0 0
10+
0.6)`. This matches the latest version of the CSS spec and browser behavior.
11+
12+
* **Potentially breaking compatibility fix**: Passing large positive or negative
13+
values to `color.adjust()` can now cause a color's channels to go outside that
14+
color's gamut. In most cases this will currently be clipped by the browser and
15+
end up showing the same color as before, but once browsers implement gamut
16+
mapping it may produce a different result.
17+
18+
* Add support for CSS Color Level 4 [color spaces]. Each color value now tracks
19+
its color space along with the values of each channel in that color space.
20+
There are two general principles to keep in mind when dealing with new color
21+
spaces:
22+
23+
1. With the exception of legacy color spaces (`rgb`, `hsl`, and `hwb`), colors
24+
will always be emitted in the color space they were defined in unless
25+
they're explicitly converted.
26+
27+
2. The `color.to-space()` function is the only way to convert a color to
28+
another color space. Some built-in functions may do operations in a
29+
different color space, but they'll always convert back to the original space
30+
afterwards.
31+
32+
* `rgb` colors can now have non-integer channels and channels outside the normal
33+
gamut of 0-255. These colors are always emitted using the `rgb()` syntax so
34+
that modern browsers that are being displayed on wide-gamut devices can
35+
display the most accurate color possible.
36+
37+
* Add support for all the new color syntax defined in Color Level 4, including:
38+
39+
* `oklab()`, `oklch()`, `lab()`, and `lch()` functions;
40+
* a top-level `hwb()` function that matches the space-separated CSS syntax;
41+
* and a `color()` function that supports the `srgb`, `srgb-linear`,
42+
`display-p3`, `a98-rgb`, `prophoto-rgb`, `rec2020`, `xyz`, `xyz-d50`, and
43+
`xyz-d65` color spaces.
44+
45+
* Add new functions for working with color spaces:
46+
47+
* `color.to-space($color, $space)` converts `$color` to the given `$space`. In
48+
most cases this conversion is lossless—the color may end up out-of-gamut for
49+
the destination color space, but browsers will generally display it as best
50+
they can regardless. However, the `hsl` and `hwb` spaces can't represent
51+
out-of-gamut colors and so will be clamped.
52+
53+
* `color.channel($color, $channel, $space: null)` returns the value of the
54+
given `$channel` in `$color`, after converting it to `$space` if necessary.
55+
It should be used instead of the old channel-specific functions such as
56+
`color.red()` and `color.hue()`.
57+
58+
* `color.same($color1, $color2)` returns whether two colors represent the same
59+
color even across color spaces. It differs from `$color1 == $color2` because
60+
`==` never consider colors in different (non-legacy) spaces as equal.
61+
62+
* `color.is-in-gamut($color, $space: null)` returns whether `$color` is
63+
in-gamut for its color space (or `$space` if it's passed).
64+
65+
* `color.to-gamut($color, $space: null)` returns `$color` constrained to its
66+
space's gamut (or to `$space`'s gamut, if passed). This is generally not
67+
recommended since even older browsers will display out-of-gamut colors as
68+
best they can, but it may be necessary in some cases.
69+
70+
* `color.space($color)`: Returns the name of `$color`'s color space.
71+
72+
* `color.is-legacy($color)`: Returns whether `$color` is in a legacy color
73+
space (`rgb`, `hsl`, or `hwb`).
74+
75+
* `color.is-powerless($color, $channel, $space: null)`: Returns whether the
76+
given `$channel` of `$color` is powerless in `$space` (or its own color
77+
space). A channel is "powerless" if its value doesn't affect the way the
78+
color is displayed, such as hue for a color with 0 chroma.
79+
80+
* `color.is-missing($color, $channel)`: Returns whether `$channel`'s value is
81+
missing in `$color`. Missing channels can be explicitly specified using the
82+
special value `none` and can appear automatically when `color.to-space()`
83+
returns a color with a powerless channel. Missing channels are usually
84+
treated as 0, except when interpolating between two colors and in
85+
`color.mix()` where they're treated as the same value as the other color.
86+
87+
* Update existing functions to support color spaces:
88+
89+
* `hsl()` and `color.hwb()` no longer forbid out-of-bounds values. Instead,
90+
they follow the CSS spec by clamping them to within the allowed range.
91+
92+
* `color.change()`, `color.adjust()`, and `color.scale()` now support all
93+
channels of all color spaces. However, if you want to modify a channel
94+
that's not in `$color`'s own color space, you have to explicitly specify the
95+
space with the `$space` parameter. (For backwards-compatibility, this
96+
doesn't apply to legacy channels of legacy colors—for example, you can still
97+
adjust an `rgb` color's saturation without passing `$space: hsl`).
98+
99+
* `color.mix()` and `color.invert()` now support the standard CSS algorithm
100+
for interpolating between two colors (the same one that's used for gradients
101+
and animations). To use this, pass the color space to use for interpolation
102+
to the `$method` parameter. For polar color spaces like `hsl` and `oklch`,
103+
this parameter also allows you to specify how hue interpolation is handled.
104+
105+
* `color.complement()` now supports a `$space` parameter that indicates which
106+
color space should be used to take the complement.
107+
108+
* `color.grayscale()` now operates in the `oklch` space for non-legacy colors.
109+
110+
* `color.ie-hex-str()` now automatically converts its color to the `rgb` space
111+
and gamut-maps it so that it can continue to take colors from any color
112+
space.
113+
114+
[color spaces]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
115+
116+
* The following functions are now deprecated, and uses should be replaced with
117+
the new color-space-aware functions defined above:
118+
119+
* The `color.red()`, `color.green()`, `color.blue()`, `color.hue()`,
120+
`color.saturation()`, `color.lightness()`, `color.whiteness()`, and
121+
`color.blackness()` functions, as well as their global counterparts, should
122+
be replaced with calls to `color.channel()`.
123+
124+
* The global `adjust-hue()`, `saturate()`, `desaturate()`, `lighten()`,
125+
`darken()`, `transaprentize()`, `fade-out()`, `opacify()`, and `fade-in()`
126+
functions should be replaced by `color.adjust()` or `color.scale()`.
127+
3128
* Add a `global-builtin` future deprecation, which can be opted-into with the
4129
`--future-deprecation` flag or the `futureDeprecations` option in the JS or
5130
Dart API. This emits warnings when any global built-in functions that are
6131
now available in `sass:` modules are called. It will become active by default
7132
in an upcoming release alongside the `@import` deprecation.
8133

134+
### Dart API
135+
136+
* Added a `ColorSpace` class which represents the various color spaces defined
137+
in the CSS spec.
138+
139+
* Added `SassColor.space` which returns a color's color space.
140+
141+
* Added `SassColor.channels` and `.channelsOrNull` which returns a list
142+
of channel values, with missing channels converted to 0 or exposed as null,
143+
respectively.
144+
145+
* Added `SassColor.isLegacy`, `.isInGamut`, `.channel()`, `.isChannelMissing()`,
146+
`.isChannelPowerless()`, `.toSpace()`, `.toGamut()`, `.changeChannels()`, and
147+
`.interpolate()` which do the same thing as the Sass functions of the
148+
corresponding names.
149+
150+
* `SassColor.rgb()` now allows out-of-bounds and non-integer arguments.
151+
152+
* `SassColor.hsl()` and `.hwb()` now allow out-of-bounds arguments.
153+
154+
* Added `SassColor.hwb()`, `.srgb()`, `.srgbLinear()`, `.displayP3()`,
155+
`.a98Rgb()`, `.prophotoRgb()`, `.rec2020()`, `.xyzD50()`, `.xyzD65()`,
156+
`.lab()`, `.lch()`, `.oklab()`, `.oklch()`, and `.forSpace()` constructors.
157+
158+
* Deprecated `SassColor.red`, `.green`, `.blue`, `.hue`, `.saturation`,
159+
`.lightness`, `.whiteness`, and `.blackness` in favor of
160+
`SassColor.channel()`.
161+
162+
* Deprecated `SassColor.changeRgb()`, `.changeHsl()`, and `.changeHwb()` in
163+
favor of `SassColor.changeChannels()`.
164+
165+
* Added `SassNumber.convertValueToUnit()` as a shorthand for
166+
`SassNumber.convertValue()` with a single numerator.
167+
168+
* Added `InterpolationMethod` and `HueInterpolationMethod` which collectively
169+
represent the method to use to interpolate two colors.
170+
171+
### JS API
172+
173+
* Modify `SassColor` to accept a new `space` option, with support for all the
174+
new color spaces defined in Color Level 4.
175+
176+
* Add `SassColor.space` which returns a color's color space.
177+
178+
* Add `SassColor.channels` and `.channelsOrNull` which returns a list of channel
179+
values, with missing channels converted to 0 or exposed as null, respectively.
180+
181+
* Add `SassColor.isLegacy`, `.isInGamut()`, `.channel()`, `.isChannelMissing()`,
182+
`.isChannelPowerless()`, `.toSpace()`, `.toGamut()`, `.change()`, and
183+
`.interpolate()` which do the same thing as the Sass functions of the
184+
corresponding names.
185+
186+
* Deprecate `SassColor.red`, `.green`, `.blue`, `.hue`, `.saturation`,
187+
`.lightness`, `.whiteness`, and `.blackness` in favor of
188+
`SassColor.channel()`.
189+
190+
### Embedded Sass
191+
192+
* Add `Color` SassScript value, with support for all the new color spaces
193+
defined in Color Level 4.
194+
195+
* Remove `RgbColor`, `HslColor` and `HwbColor` SassScript values.
196+
9197
## 1.78.0
10198

11199
* The `meta.feature-exists` function is now deprecated. This deprecation is

‎lib/sass.dart

+6-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ export 'src/importer.dart';
3131
export 'src/logger.dart' show Logger;
3232
export 'src/syntax.dart';
3333
export 'src/value.dart'
34-
hide ColorFormat, SassApiColor, SassApiValue, SpanColorFormat;
34+
hide
35+
ColorChannel,
36+
ColorFormat,
37+
LinearChannel,
38+
SassApiColorSpace,
39+
SpanColorFormat;
3540
export 'src/visitor/serialize.dart' show OutputStyle;
3641
export 'src/evaluation_context.dart' show warn;
3742

0 commit comments

Comments
 (0)
Please sign in to comment.