From 90373ddd637d45296564ff39cb0b22646e5be2d8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 29 Dec 2020 14:32:09 -0800 Subject: [PATCH] Document new color unit behavior Partially addresses #511 See sass/sass#2904 --- data/documentation.yml | 1 + .../breaking-changes.html.md.erb | 3 + .../breaking-changes/color-units.md.erb | 79 +++++++++++++++++++ source/documentation/modules.html.md.erb | 10 +-- .../documentation/modules/color.html.md.erb | 7 +- 5 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 source/documentation/breaking-changes/color-units.md.erb diff --git a/data/documentation.yml b/data/documentation.yml index c786ab38c..d9abe9343 100644 --- a/data/documentation.yml +++ b/data/documentation.yml @@ -59,6 +59,7 @@ toc: - sass:string: /documentation/modules/string - Breaking Changes: /documentation/breaking-changes :children: + - Color Units: /documentation/breaking-changes/color-units - Extending Compound Selectors: /documentation/breaking-changes/extend-compound - CSS Variable Syntax: /documentation/breaking-changes/css-vars - Command Line: /documentation/cli diff --git a/source/documentation/breaking-changes.html.md.erb b/source/documentation/breaking-changes.html.md.erb index 5bea378b4..e05aea833 100644 --- a/source/documentation/breaking-changes.html.md.erb +++ b/source/documentation/breaking-changes.html.md.erb @@ -23,6 +23,9 @@ time-sensitive, so they may be released with new minor version numbers instead. These breaking changes are coming soon or have recently been released: +* [Color functions are becoming more strict about + units](breaking-changes/color-units) beginning in Dart Sass 1.32.0. + * [Compound selectors could not be extended](breaking-changes/extend-compound) in Dart Sass 1.0.0 and Ruby Sass 4.0.0. diff --git a/source/documentation/breaking-changes/color-units.md.erb b/source/documentation/breaking-changes/color-units.md.erb new file mode 100644 index 000000000..f6315a4b2 --- /dev/null +++ b/source/documentation/breaking-changes/color-units.md.erb @@ -0,0 +1,79 @@ +--- +title: "Breaking Change: Color Units" +introduction: > + In CSS, saturation and lightness parameters always require `%` units and hue + parameters allow any angle unit. Sass has historically ignored units for these + functions. We're in the process of changing that. +--- + +It's important that we keep Sass's implementation of [`hsl()`] consistent with +the CSS spec, and that we keep other Sass functions that deal with colors +consistent with `hsl()`. One notable place where Sass has historically differed +from the spec is the way that `hsl()` (and other color functions) handled units. + +[`hsl()`]: ../modules/color#hsl + +For hue, CSS allows any [angle unit] (`deg`, `grad`, `rad`, or `turn`). It also +allows a unitless number, which is interpreted as `deg`. Historically, Sass has +allowed *any* unit, and interpreted it as `deg`. This is particularly +problematic because it meant that the valid CSS expression `hsl(0.5turn, 100%, +50%)` would be allowed by Sass but interpreted entirely wrong. + +[angle unit]: https://drafts.csswg.org/css-values-4/#angles + +For lightness and saturation, CSS only allows `%` units. Even unitless numbers +aren't allowed (unlike for the hue). Historically, Sass has allowed *any* unit, +and interpreted it as `%`. You could even write `hsl(0, 100px, 50s)` and Sass +would return the color `red`. + +To fix this issue and bring Sass in line with the CSS spec, we're making changes +in multiple phases: + +## Phase 1 + +<% impl_status dart: '1.32.0', libsass: false, ruby: false %> + +To begin with, we're just introducing deprecation warnings for behaviors that we +plan to change. Specifically, Sass will emit a deprecation warning if you do any +of the following: + +* Pass a number with a unit other than `deg` as a hue to any function. Passing a + unitless number is still allowed. + +* Pass a unitless number as saturation or lightness to any function. + +* Pass a number with a unit other than `%` as saturation or lightness to any + function. + +Of these warnings, the first is the most important one to deal with immediately +specifically if you're passing a number with unit `grad`, `rad`, or `turn`. This +case will change behavior in Phase 2, which could change how your stylesheets +render if you don't update them. + +## Phase 2 + +<% impl_status dart: false, libsass: false, ruby: false %> + +At least three months after the launch of Phase 1, we'll change the way angle +units are handled for hue parameters to match the CSS spec. This means that +numbers with `grad`, `rad`, or `turn` units will be converted to `deg`: +`0.5turn` will be converted to `180deg`, `100grad` will be converted to `90deg`, +and so on. + +Because this change is necessary to preserve CSS compatibility, according to the +[Dart Sass compatibility policy] it will be made with only a minor version bump. +However, it changes as little behavior as possible to ensure that Sass +interprets all valid CSS according to the CSS spec. All other deprecated +behavior will remain in place until Phase 3. + +[Dart Sass compatibility policy]: https://github.com/sass/dart-sass#compatibility-policy + +## Phase 3 + +<% impl_status dart: false, libsass: false, ruby: false %> + +Finally, we'll remove all deprecated behavior by making color functions throw +errors if they're passed any units that produced deprecation warnings in Phase +1. Because this is a breaking change that's not strictly necessary for CSS +compatibility, we'll land it as part of Dart Sass 2.0.0 (which we have no +immediate plans to release). diff --git a/source/documentation/modules.html.md.erb b/source/documentation/modules.html.md.erb index de8190ebb..4a3357c85 100644 --- a/source/documentation/modules.html.md.erb +++ b/source/documentation/modules.html.md.erb @@ -118,11 +118,11 @@ Sass provides the following built-in modules: [hue, saturation, and lightness]: https://en.wikipedia.org/wiki/HSL_and_HSV - The hue is a number between `0deg` and `360deg` (inclusive). The saturation - and lightness are numbers between `0%` and `100%` (inclusive). All these - numbers may be [unitless][]. The alpha channel can be specified as either a - unitless number between 0 and 1 (inclusive), or a percentage between `0%` and - `100%` (inclusive). + The hue is a number between `0deg` and `360deg` (inclusive) and may be + unitless. The saturation and lightness are numbers between `0%` and `100%` + (inclusive) and may *not* be unitless. The alpha channel can be specified as + either a unitless number between 0 and 1 (inclusive), or a percentage between + `0%` and `100%` (inclusive). [unitless]: values/numbers#units diff --git a/source/documentation/modules/color.html.md.erb b/source/documentation/modules/color.html.md.erb index e07231199..a211e2b2f 100644 --- a/source/documentation/modules/color.html.md.erb +++ b/source/documentation/modules/color.html.md.erb @@ -29,7 +29,7 @@ SIGNATURE arguments must be [unitless][] and between -255 and 255 (inclusive). The `$hue` argument must have either the unit `deg` or no unit. The `$saturation`, `$lightness`, `$whiteness`, and `$blackness` arguments must be between `-100%` - and `100%` (inclusive), and may be unitless. The `$alpha` argument must be + and `100%` (inclusive), and may not be unitless. The `$alpha` argument must be unitless and between -1 and 1 (inclusive). [unitless]: ../values/numbers#units @@ -55,7 +55,8 @@ SIGNATURE Increases or decreases `$color`'s hue. The `$hue` must be a number between `-360deg` and `360deg` (inclusive) to add - to `$color`'s hue. It may be [unitless][]. + to `$color`'s hue. It may be [unitless][] but it may not have any unit other + than `deg`. [unitless]: ../values/numbers#units @@ -203,7 +204,7 @@ SIGNATURE arguments must be [unitless][] and between 0 and 255 (inclusive). The `$hue` argument must have either the unit `deg` or no unit. The `$saturation`, `$lightness`, `$whiteness`, and `$blackness` arguments must be between `0%` - and `100%` (inclusive), and may be unitless. The `$alpha` argument must be + and `100%` (inclusive), and may not be unitless. The `$alpha` argument must be unitless and between -1 and 1 (inclusive). [unitless]: ../values/numbers#units