Skip to content

v1.6.0

Compare
Choose a tag to compare
@devongovett devongovett released this 10 Mar 15:47
· 463 commits to master since this release

This release brings more CSS Color goodies including the new color-mix() function, gamut mapping for color conversions, support for none components, and more.

color-mix()

The color-mix() function from the CSS Color Level 5 spec allows you to mix two colors together by a specified amount. This works similarly to defining a gradient between two colors, and then choosing the interpolated value somewhere in between.

This syntax is currently available behind a flag in Safari TP, but Parcel CSS parses this function and converts it to a color definition that current browsers can understand.

color-mix(in lch, teal 65%, olive);

results in:

lch(49.4431% 40.4806 162.546);

You get a ton of control over how colors are mixed as well. In addition to choosing how much of each color to mix in, you can choose which color space interpolation occurs in as well as control how hues are mixed. For example:

color-mix(in lch longer hue, teal 65%, olive);

results in:

lch(49.4431% 40.4806 288.546);

Parcel CSS will also convert this color to a legacy RGB color supported by older browsers as well if needed.

Learn more about color-mix() and interpolation in the spec, and try it out!

none components

Colors can now also have components that are defined as none. For example, hsl(none 20% 40%). This defines an HSL color where the hue component is "missing". If rendered directly, this is equivalent to a value of 0. However, these missing components are interpreted differently when mixing colors using color-mix(). In this case, the none component is replaced by the corresponding component in the other color. For example:

color-mix(in hsl, hsl(none 20% 40%), hsl(30deg none 80%));

is equivalent to:

hsl(30deg 20% 60%)

The none components of each color are replaced with the other, and the remaining ones are interpolated.

This can also happen automatically in some cases, when components are deemed "powerless". Read more about how this works in the spec.

Gamut mapping

Some color spaces have a higher color gamut than others. This means the range of valid values is wider, i.e. it can represent more colors. For example, the P3 color space can represent around 25% more colors than sRGB. When converting between color spaces, we need to decide how to handle these "out of gamut" colors. Previously, this was done by clipping. For example, color(display-p3 0 1 0) would become rgb(0, 255, 0). However, this can result in strange behavior in some cases, where you end up with a very different looking color because the relative amounts of each channel changed when one of them is clipped.

Now, Parcel CSS implements Gamut Mapping as defined in the CSS Color spec. This attempts to find a closer color to the intended one within the gamut of the target color space by converting the color to the OKLab color space and adjusting the chroma component (i.e. how "colorful" it is) until the result is within the color gamut and "close enough" to the original color. The above example now converts to rgb(0, 249, 66) instead of rgb(0, 255, 0).

More improvements

  • If you're using the Rust API, each color format is now represented as a struct and you can convert between them easily using Rust's From and Into traits.
  • Color fallback generation is improved so that we generate fewer fallbacks when not needed.
  • Fixed the order of border and border-image declarations in generated code.