diff --git a/config.rb b/config.rb index 5b0c57402..d8ba7d553 100644 --- a/config.rb +++ b/config.rb @@ -71,6 +71,11 @@ redirect "d/#{basename}.html", to: "/documentation/breaking-changes/#{basename}" end +for url in %w[d/random-with-units documentation/breaking-changes/random-with-units + d/breaking-changes/color-units documentation/breaking-changes/color-units] do + redirect url, to: "/documentation/breaking-changes/function-units" +end + redirect 'tutorial.html', to: '/guide' redirect 'download.html', to: '/install' redirect 'try.html', to: 'https://www.sassmeister.com' diff --git a/source/documentation/breaking-changes.html.md.erb b/source/documentation/breaking-changes.html.md.erb index 10da4a7f7..7ca5807dc 100644 --- a/source/documentation/breaking-changes.html.md.erb +++ b/source/documentation/breaking-changes.html.md.erb @@ -23,18 +23,15 @@ time-sensitive, so they may be released with new minor version numbers instead. These breaking changes are coming soon or have recently been released: -* [`random()` with units](breaking-changes/random-with-units) beginning in Dart - Sass 1.54.5. +* [Functions are stricter about which units they + allow](breaking-changes/function-units) beginning in Dart Sass 1.32.0. -* [Selectors with invalid combinators will be +* [Selectors with invalid combinators are invalid](breaking-changes/bogus-combinators) beginning in Dart Sass 1.54.0. * [`/` is changing from a division operation to a list separator](breaking-changes/slash-div) beginning in Dart Sass 1.33.0. -* [Color functions are becoming more strict about - units](breaking-changes/color-units) beginning in Dart Sass 1.32.0. - * [Parsing the special syntax of `@-moz-document` will be invalid](breaking-changes/moz-document) beginning in Dart Sass 1.7.2. diff --git a/source/documentation/breaking-changes/color-units.md.erb b/source/documentation/breaking-changes/color-units.md.erb deleted file mode 100644 index aad47a506..000000000 --- a/source/documentation/breaking-changes/color-units.md.erb +++ /dev/null @@ -1,79 +0,0 @@ ---- -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#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/breaking-changes/function-units.md.erb b/source/documentation/breaking-changes/function-units.md.erb new file mode 100644 index 000000000..1194d6601 --- /dev/null +++ b/source/documentation/breaking-changes/function-units.md.erb @@ -0,0 +1,208 @@ +--- +title: "Breaking Change: Strict Function Units" +introduction: > + Various built-in functions will become stricter in which units they allow + and will handle those units more consistently. This makes Sass more compatible + with the CSS spec and helps catch errors more quickly. +--- + +## Hue + +<% impl_status dart: '1.32.0', libsass: false, ruby: false %> + +When specifying a color's 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. + +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 %> + +At first, Sass just emitted a deprecation warning if you passed a number with a +unit other than `deg` as a hue to any function. Passing a unitless number was +still allowed. + +### Phase 2 + +<% impl_status dart: '1.52.1', libsass: false, ruby: false %> + +Next, we changed 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 was 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. + +[Dart Sass compatibility policy]: https://github.com/sass/dart-sass#compatibility-policy + +### Phase 3 + +<% impl_status dart: false, libsass: false, ruby: false %> + +Finally, in Dart Sass 2.0.0 color functions will throw errors if they're passed +a hue parameter with a non-angle unit. Unitless hues will still be allowed. + +## Saturation and Lightness + +When specifying an HSL color's saturation and lightness, 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 two phases: + +### Phase 1 + +<% impl_status dart: '1.32.0', libsass: false, ruby: false %> + +Currently, Sass just emits a deprecation warning if you pass a number with a +unit other than `deg` as a hue to any function. Passing a unitless number was +still allowed. + +### Phase 2 + +<% impl_status dart: false, libsass: false, ruby: false %> + +In Dart Sass 2.0.0 color functions will throw errors if they're passed a +saturation or lightness parameter with no unit or a non-`%` unit. + +## Alpha + +When specifying a color's alpha value, CSS (as of [Colors Level 4]) allows +either unitless values between 0 and 1 or `%` values between `0%` and `100%`. In +most cases Sass follows this behavior, but the functions `color.adjust()` and +`color.change()` have historically allowed *any* unit, and interpreted it as +unitless. You could even write `color.change(red, $alpha: 1%)` and Sass would +return the opaque color `black`. + +[Colors Level 4]: https://www.w3.org/TR/css-color-4/#typedef-alpha-value + +To fix this issue and bring Sass in line with the CSS spec, we're making changes +in three phases: + +### Phase 1 + +<% impl_status dart: '1.55.1', libsass: false, ruby: false %> + +Currently, Sass just emits a deprecation warning if you pass a number with any +unit, including `%`, as an alpha value to `color.change()` or `color.adjust()`. + +### Phase 2 + +<% impl_status dart: false, libsass: false, ruby: false %> + +Next, we'll change the way `%` units are handled for the alpha argument to +`color.change()` and `color.adjust()`. Alphas with unit `%` will be divided by +`100%`, converting them to unitless numbers between 0 and 1. + +Because this change is a bug fix that improves consistency with other Sass +functions, it will be made with only a minor version bump. It will be changed at +minimum three months after Phase 1 is released, to give users time to adjust +their code and avoid the bug. + +[Dart Sass compatibility policy]: https://github.com/sass/dart-sass#compatibility-policy + +### Phase 3 + +<% impl_status dart: false, libsass: false, ruby: false %> + +Finally, in Dart Sass 2.0.0 `color.change()` and `color.adjust()` will throw +errors if they're passed an alpha parameter with a non-`%` unit. Unitless alphas +will still be allowed. + +## `math.random()` + +[The `math.random()` function] has historically ignored units in `$limit` and +returned a unitless value. For example `math.random(100px)` would drop "px" and +return a value like `42`. + +A future version of Sass will stop ignoring units for the `$limit` argument and +return a random integer with the same units. + +[The `math.random()` function]: ../modules/math#random + +<% example(autogen_css: false) do %> + // Future Sass, doesn't work yet! + @debug math.random(100px); // 42px + === + // Future Sass, doesn't work yet! + @debug math.random(100px) // 42px +<% end %> + +### Phase 1 + +<% impl_status dart: '1.54.5', libsass: false, ruby: false %> + +Currently, Sass emits a deprecation warning if you pass a `$limit` with units to +`math.random()`. + +### Phase 2 + +<% impl_status dart: false, libsass: false, ruby: false %> + +In Dart Sass 2.0.0, passing a `$limit` number with units will be an error. + +### Phase 3 + +<% impl_status dart: false, libsass: false, ruby: false %> + +In a minor release after Dart Sass 2.0.0, passing a `$limit` number with units +to the `math.random()` function will be allowed again. It will return a random +integer the same units as `$limit`, instead of a unitless number. + +## Weight + +The [`color.mix()` function] and [`color.invert()` function] have both +historically ignored units in their `$weight` arguments, despite that argument +conceptually representing a percentage. A future version of Sass will require +the unit `%`. + +[`color.mix()` function]: ../modules/color#mix +[`color.invert()` function]: ../modules/color#invert + +### Phase 1 + +<% impl_status dart: '1.55.1', libsass: false, ruby: false %> + +Currently, Sass emits a deprecation warning if you pass a `$weight` with no +units or with units other than `%` to `color.mix()` or `color.invert()`. + +### Phase 2 + +<% impl_status dart: false, libsass: false, ruby: false %> + +In Dart Sass 2.0.0, `color.mix()` and `color.invert()` will throw errors if +they're passed a `$weight` with no unit or a non-`%` unit. + +## Index + +The [`list.nth()` function] and [`list.set-nth()` function] have both +historically ignored units in their `$n` arguments. A future version of Sass +will forbid any units. + +[`list.nth()` function]: ../modules/color#nth +[`list.set-nth()` function]: ../modules/color#set-nth + +### Phase 1 + +<% impl_status dart: '1.55.1', libsass: false, ruby: false %> + +Currently, Sass emits a deprecation warning if you pass a `$weight` with no +units or with units other than `%` to `color.mix()` or `color.invert()`. + +### Phase 2 + +<% impl_status dart: false, libsass: false, ruby: false %> + +In Dart Sass 2.0.0, `list.nth()` and `list.set-nth()` will throw errors if +they're passed an index `$n` with a unit. diff --git a/source/documentation/breaking-changes/random-with-units.md.erb b/source/documentation/breaking-changes/random-with-units.md.erb deleted file mode 100644 index 900453e22..000000000 --- a/source/documentation/breaking-changes/random-with-units.md.erb +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: "Breaking Change: Random With Units" -introduction: > - The `random()` function will no longer ignore units on the `$limit` argument - in a future version. Passing a `$limit` with units is deprecated to ensure the - compilation results don't change once the new behavior lands. ---- - -[The `random()` function] has historically ignored units in `$limit` and -returned a unitless value. For example `random(100px)` would drop "px" and -return a value like `42`. - -A future implementation of Dart Sass will stop ignoring units for the `$limit` -argument and return a random integer with the same units. - -[The `random()` function]: ../modules/math#random - -<% example(autogen_css: false) do %> - // Future Sass, doesn't work yet! - @debug math.random(100px); // 42px - === - // Future Sass, doesn't work yet! - @debug math.random(100px) // 42px -<% end %> - -## Transition Period - -<% impl_status dart: '1.54.5', libsass: false, ruby: false %> - -First, the Sass compiler will emit a deprecation warning for previous uses of -`random()` when the `$limit` argument has units. The warning will suggest a way -to preserve the existing behavior and another way that emulates the future -implementation. - -In Dart 2.0.0 passing a `$limit` number with units will be an error, and then in -a future minor release the `random()` function will return a random integer the -same units as `$limit`.