diff --git a/source/_includes/code_snippets/example-advanced-nesting.liquid b/source/_includes/code_snippets/example-advanced-nesting.liquid index 859a763..c0ea94b 100644 --- a/source/_includes/code_snippets/example-advanced-nesting.liquid +++ b/source/_includes/code_snippets/example-advanced-nesting.liquid @@ -36,12 +36,4 @@ uses the [`selector.unify()` function][] to combine `&` with a user's selector. @include unify-parent("select") /* ... */ - === - .wrapper input.field { - /* ... */ - } - - .wrapper select.field { - /* ... */ - } {% endcodeExample %} diff --git a/source/documentation/at-rules/control/if.md b/source/documentation/at-rules/control/if.md index 865f394..8336669 100644 --- a/source/documentation/at-rules/control/if.md +++ b/source/documentation/at-rules/control/if.md @@ -130,15 +130,6 @@ evaluated if every other block fails. .next @include triangle(5px, black, right) - === - .next { - height: 0; - width: 0; - border-color: transparent; - border-style: solid; - border-width: 2.5px; - border-left-color: black; - } {% endcodeExample %} {% render 'doc_snippets/truthiness-and-falsiness' %} diff --git a/source/documentation/at-rules/control/while.md b/source/documentation/at-rules/control/while.md index 0778329..236f360 100644 --- a/source/documentation/at-rules/control/while.md +++ b/source/documentation/at-rules/control/while.md @@ -36,10 +36,6 @@ introduction: > $normal-font-size: 16px sup font-size: scale-below(20px, 16px) - === - sup { - font-size: 12.36094px; - } {% endcodeExample %} {% headsUp %} diff --git a/source/documentation/at-rules/css.md b/source/documentation/at-rules/css.md index cb1458e..58b73ef 100644 --- a/source/documentation/at-rules/css.md +++ b/source/documentation/at-rules/css.md @@ -71,7 +71,7 @@ having to rewrite the style rule's selector. [range context]: https://www.w3.org/TR/mediaqueries-4/#mq-range-context - {% codeExample 'range-syntax', false %} + {% codeExample 'range-syntax' %} @media (width <= 700px) { body { background: green; @@ -81,12 +81,6 @@ having to rewrite the style rule's selector. @media (width <= 700px) body background: green - === - @media (width <= 700px) { - body { - background: green; - } - } {% endcodeExample %} {% endcompatibility %} diff --git a/source/documentation/breaking-changes/bogus-combinators.liquid b/source/documentation/breaking-changes/bogus-combinators.liquid deleted file mode 100644 index 37cd2ce..0000000 --- a/source/documentation/breaking-changes/bogus-combinators.liquid +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: 'Breaking Change: Invalid Combinators' -introduction: > - Sass has historically been very permissive about the use of leading, trailing, - and repeated combinators in selectors. These combinators are being deprecated - except where they're useful for nesting. ---- - -{% markdown %} - Sass has historically supported three invalid uses of combinators: - - * Leading combinators, as in `+ .error {color: red}`. - - * Trailing combinators, as in `.error + {color: red}`. - - * Repeated combinators, as in `div > > .error {color: red}`. - - None of these are valid CSS, and all of them will cause browsers to ignore the - style rule in question. Supporting them added a substantial amount of - complexity to Sass's implementation, and made it particularly difficult to fix - various bugs related to the `@extend` rule. As such, we [made the decision] to - remove support for these uses. - - [made the decision]: https://github.com/sass/sass/issues/3340 - - **There is one major exception**: leading and trailing combinators may still - be used for nesting purposes. For example, the following is still very much - supported: -{% endmarkdown %} - -{% codeExample 'bogus-combinators' %} - .sidebar > { - .error { - color: red; - } - } - === - .sidebar > - .error - color: red -{% endcodeExample %} - -{% markdown %} - Sass will only produce an error if a selector still has a leading or trailing - combinator _after nesting is resolved_. Repeated combinators, on the other - hand, will always be errors. - - To make sure existing stylesheets who (likely accidentally) contain invalid - combinators, we'll support a transition period until the next major release of - Dart Sass. - - ## Transition Period - - {% compatibility 'dart: "1.54.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - First, we'll emit deprecation warnings for all double combinators, as well as - leading or trailing combinators that end up in selectors after nesting is - resolved. - - {% render 'doc_snippets/silence-deprecations' %} - - In addition, we'll immediately start omitting selectors that we know to be - invalid CSS from the compiled CSS, with one exception: we _won't_ omit - selectors that begin with a leading combinator, since they may be used from a - nested `@import` rule or `meta.load-css()` mixin. However, we don't encourage - this pattern and will drop support for it in Dart Sass 2.0.0. -{% endmarkdown %} diff --git a/source/documentation/breaking-changes/bogus-combinators.md b/source/documentation/breaking-changes/bogus-combinators.md new file mode 100644 index 0000000..8a21cbe --- /dev/null +++ b/source/documentation/breaking-changes/bogus-combinators.md @@ -0,0 +1,63 @@ +--- +title: 'Breaking Change: Invalid Combinators' +introduction: > + Sass has historically been very permissive about the use of leading, trailing, + and repeated combinators in selectors. These combinators are being deprecated + except where they're useful for nesting. +--- + +Sass has historically supported three invalid uses of combinators: + +* Leading combinators, as in `+ .error {color: red}`. + +* Trailing combinators, as in `.error + {color: red}`. + +* Repeated combinators, as in `div > > .error {color: red}`. + +None of these are valid CSS, and all of them will cause browsers to ignore the +style rule in question. Supporting them added a substantial amount of complexity +to Sass's implementation, and made it particularly difficult to fix various bugs +related to the `@extend` rule. As such, we [made the decision] to remove support +for these uses. + +[made the decision]: https://github.com/sass/sass/issues/3340 + +**There is one major exception**: leading and trailing combinators may still be +used for nesting purposes. For example, the following is still very much +supported: + +{% codeExample 'bogus-combinators' %} + .sidebar > { + .error { + color: red; + } + } + === + .sidebar > + .error + color: red +{% endcodeExample %} + +Sass will only produce an error if a selector still has a leading or trailing +combinator _after nesting is resolved_. Repeated combinators, on the other hand, +will always be errors. + +To make sure existing stylesheets who (likely accidentally) contain invalid +combinators, we'll support a transition period until the next major release of +Dart Sass. + +## Transition Period + +{% compatibility 'dart: "1.54.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +First, we'll emit deprecation warnings for all double combinators, as well as +leading or trailing combinators that end up in selectors after nesting is +resolved. + +{% render 'doc_snippets/silence-deprecations' %} + +In addition, we'll immediately start omitting selectors that we know to be +invalid CSS from the compiled CSS, with one exception: we _won't_ omit selectors +that begin with a leading combinator, since they may be used from a nested +`@import` rule or `meta.load-css()` mixin. However, we don't encourage this +pattern and will drop support for it in Dart Sass 2.0.0. diff --git a/source/documentation/breaking-changes/css-vars.liquid b/source/documentation/breaking-changes/css-vars.liquid deleted file mode 100644 index 6e8bbf9..0000000 --- a/source/documentation/breaking-changes/css-vars.liquid +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: 'Breaking Change: CSS Variable Syntax' -introduction: > - Older versions of LibSass and Ruby Sass parsed custom property declarations - just like any other property declaration, allowing the full range of - [SassScript expressions](/documentation/syntax/structure#expressions) as - values. But this wasn't compatible with CSS. ---- - -{% compatibility 'dart: true', 'libsass: "3.5.0"', 'ruby: "3.5.0"' %}{% endcompatibility %} - -{% markdown %} - The CSS spec allows almost any string of characters to be used in a custom - property declaration. Even though these values might not be meaningful for any - CSS property, they could be accessed from JavaScript. When they were parsed as - SassScript values, syntax that would have been valid plain CSS failed to - parse. For example, the [Polymer library][] used this to support plain-CSS - mixins: - - [Polymer library]: https://polymer-library.polymer-project.org/3.0/docs/devguide/custom-css-properties#use-custom-css-mixins -{% endmarkdown %} - -{% codeExample 'css-vars', false, 'scss' %} - :root { - --flex-theme: { - border: 1px solid var(--theme-dark-blue); - font-family: var(--theme-font-family); - padding: var(--theme-wide-padding); - background-color: var(--theme-light-blue); - }; - } - === - :root { - --flex-theme: { - border: 1px solid var(--theme-dark-blue); - font-family: var(--theme-font-family); - padding: var(--theme-wide-padding); - background-color: var(--theme-light-blue); - }; - } -{% endcodeExample %} - -{% markdown %} - To provide maximum compatibility with plain CSS, more recent versions of Sass - require SassScript expressions in custom property values to be written within - [interpolation](/documentation/interpolation). Interpolation will also work - for older Sass versions, and so is recommended for all stylesheets. -{% endmarkdown %} - -{% codeExample 'css-vars-interpolation' %} - $accent-color: #fbbc04; - - :root { - // WRONG, will not work in recent Sass versions. - --accent-color-wrong: $accent-color; - - // RIGHT, will work in all Sass versions. - --accent-color-right: #{$accent-color}; - } - === - $accent-color: #fbbc04 - - :root - // WRONG, will not work in recent Sass versions. - --accent-color-wrong: $accent-color - - // RIGHT, will work in all Sass versions. - --accent-color-right: #{$accent-color} - === - :root { - --accent-color-wrong: $accent-color; - --accent-color-right: #fbbc04; - } -{% endcodeExample %} - -{% headsUp false %} - {% markdown %} - Because interpolation removes quotation marks from quoted strings, it may be - necessary to wrap them in the [`meta.inspect()` function][] to preserve - their quotes. - - [`meta.inspect()` function]: /documentation/modules/meta#inspect - {% endmarkdown %} - - {% codeExample 'css-vars-heads-up' %} - @use "sass:meta"; - - $font-family-monospace: Menlo, Consolas, "Courier New", monospace; - - :root { - --font-family-monospace: #{meta.inspect($font-family-monospace)}; - } - === - @use "sass:meta" - - $font-family-monospace: Menlo, Consolas, "Courier New", monospace - - :root - --font-family-monospace: #{meta.inspect($font-family-monospace)} - === - :root { - --font-family-monospace: Menlo, Consolas, "Courier New", monospace; - } - {% endcodeExample %} -{% endheadsUp %} diff --git a/source/documentation/breaking-changes/css-vars.md b/source/documentation/breaking-changes/css-vars.md new file mode 100644 index 0000000..f50c1d4 --- /dev/null +++ b/source/documentation/breaking-changes/css-vars.md @@ -0,0 +1,80 @@ +--- +title: 'Breaking Change: CSS Variable Syntax' +introduction: > + Older versions of LibSass and Ruby Sass parsed custom property declarations + just like any other property declaration, allowing the full range of + [SassScript expressions](/documentation/syntax/structure#expressions) as + values. But this wasn't compatible with CSS. +--- + +{% compatibility 'dart: true', 'libsass: "3.5.0"', 'ruby: "3.5.0"' %}{% endcompatibility %} + +The CSS spec allows almost any string of characters to be used in a custom +property declaration. Even though these values might not be meaningful for any +CSS property, they could be accessed from JavaScript. When they were parsed as +SassScript values, syntax that would have been valid plain CSS failed to parse. +For example, the [Polymer library][] used this to support plain-CSS mixins: + +[Polymer library]: https://polymer-library.polymer-project.org/3.0/docs/devguide/custom-css-properties#use-custom-css-mixins + +{% codeExample 'css-vars', true, 'scss' %} + :root { + --flex-theme: { + border: 1px solid var(--theme-dark-blue); + font-family: var(--theme-font-family); + padding: var(--theme-wide-padding); + background-color: var(--theme-light-blue); + }; + } +{% endcodeExample %} + +To provide maximum compatibility with plain CSS, more recent versions of Sass +require SassScript expressions in custom property values to be written within +[interpolation](/documentation/interpolation). Interpolation will also work for +older Sass versions, and so is recommended for all stylesheets. + +{% codeExample 'css-vars-interpolation' %} + $accent-color: #fbbc04; + + :root { + // WRONG, will not work in recent Sass versions. + --accent-color-wrong: $accent-color; + + // RIGHT, will work in all Sass versions. + --accent-color-right: #{$accent-color}; + } + === + $accent-color: #fbbc04 + + :root + // WRONG, will not work in recent Sass versions. + --accent-color-wrong: $accent-color + + // RIGHT, will work in all Sass versions. + --accent-color-right: #{$accent-color} +{% endcodeExample %} + +{% headsUp %} + Because interpolation removes quotation marks from quoted strings, it may be + necessary to wrap them in the [`meta.inspect()` function][] to preserve their + quotes. + + [`meta.inspect()` function]: /documentation/modules/meta#inspect + + {% codeExample 'css-vars-heads-up' %} + @use "sass:meta"; + + $font-family-monospace: Menlo, Consolas, "Courier New", monospace; + + :root { + --font-family-monospace: #{meta.inspect($font-family-monospace)}; + } + === + @use "sass:meta" + + $font-family-monospace: Menlo, Consolas, "Courier New", monospace + + :root + --font-family-monospace: #{meta.inspect($font-family-monospace)} + {% endcodeExample %} +{% endheadsUp %} diff --git a/source/documentation/breaking-changes/extend-compound.liquid b/source/documentation/breaking-changes/extend-compound.liquid deleted file mode 100644 index a26788c..0000000 --- a/source/documentation/breaking-changes/extend-compound.liquid +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: 'Breaking Change: Extending Compound Selectors' -introduction: > - LibSass currently allows compound selectors like `.message.info` to be - [extended](/documentation/at-rules/extend), but the way it was extended - doesn't match the way `@extend` is meant to work. ---- - -{% compatibility 'dart: true', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - -{% markdown %} - When one selector extends another, Sass styles all elements that match the - extender as though they also match the class being extended. In other words, - if you write `.heads-up {@extend .info}`, it works just like you replaced - `class="heads-up"` in your HTML with `class="heads-up info"`. - - Following that logic, you'd expect that `.heads-up {@extend .message.info}` to - work like replacing `class="heads-up"` with `class="heads-up info message"`. - But that's not how it works right now in LibSass and Ruby Sass--instead of - adding `.heads-up` to every selector that has *either `.info` or `.message`*, - it only adds it to selectors that have *`.info.message` together*. -{% endmarkdown %} - -{% codeExample 'extend-compound-bad', false %} - // These should both be extended, but they won't be. - .message { - border: 1px solid black; - } - .info { - font-size: 1.5rem; - } - - .heads-up { - @extend .message.info; - } - === - // These should both be extended, but they won't be. - .message - border: 1px solid black - - .info - font-size: 1.5rem - - - .heads-up - @extend .message.info -{% endcodeExample %} - -{% markdown %} - To fix this issue, avoid more confusion, and keep the implementation clean and - efficient the ability to extend compound selectors is unsupported in Dart Sass - and will be removed in a future version of LibSass. For compatibility, users - should extend each simple selector separately instead: -{% endmarkdown %} - -{% codeExample 'extend-compound-good' %} - .message { - border: 1px solid black; - } - .info { - font-size: 1.5rem; - } - - .heads-up { - @extend .message, .info; - } - === - .message - border: 1px solid black - - .info - font-size: 1.5rem - - - .heads-up - @extend .message, .info -{% endcodeExample %} - -{% headsUp false %} - {% markdown %} - Because Sass doesn't know the details of the HTML the CSS is going to style, - any `@extend` might need to generate extra selectors that won't apply to - your HTML in particular. This is especially true when switching away from - extending compound selectors. - - Most of the time, these extra selectors won't cause any problems, and will - only add a couple extra bytes to gzipped CSS. But some stylesheets might be - relying more heavily on the old behavior. In that case, we recommend - replacing the compound selector with a [placeholder selector][]. - - [placeholder selector]: /documentation/style-rules/placeholder-selectors - {% endmarkdown %} - - {% codeExample 'extend-compound-heads-up' %} - // Instead of just `.message.info`. - %message-info, .message.info { - border: 1px solid black; - font-size: 1.5rem; - } - - .heads-up { - // Instead of `.message.info`. - @extend %message-info; - } - === - // Instead of just `.message.info`. - %message-info, .message.info - border: 1px solid black - font-size: 1.5rem - - - .heads-up - // Instead of `.message.info`. - @extend %message-info - {% endcodeExample %} -{% endheadsUp %} diff --git a/source/documentation/breaking-changes/extend-compound.md b/source/documentation/breaking-changes/extend-compound.md new file mode 100644 index 0000000..bda39e9 --- /dev/null +++ b/source/documentation/breaking-changes/extend-compound.md @@ -0,0 +1,110 @@ +--- +title: 'Breaking Change: Extending Compound Selectors' +introduction: > + LibSass currently allows compound selectors like `.message.info` to be + [extended](/documentation/at-rules/extend), but the way it was extended + doesn't match the way `@extend` is meant to work. +--- + +{% compatibility 'dart: true', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +When one selector extends another, Sass styles all elements that match the +extender as though they also match the class being extended. In other words, if +you write `.heads-up {@extend .info}`, it works just like you replaced +`class="heads-up"` in your HTML with `class="heads-up info"`. + +Following that logic, you'd expect that `.heads-up {@extend .message.info}` to +work like replacing `class="heads-up"` with `class="heads-up info message"`. But +that's not how it works right now in LibSass and Ruby Sass--instead of adding +`.heads-up` to every selector that has *either `.info` or `.message`*, it only +adds it to selectors that have *`.info.message` together*. + +{% codeExample 'extend-compound-bad', false %} + // These should both be extended, but they won't be. + .message { + border: 1px solid black; + } + .info { + font-size: 1.5rem; + } + + .heads-up { + @extend .message.info; + } + === + // These should both be extended, but they won't be. + .message + border: 1px solid black + + .info + font-size: 1.5rem + + + .heads-up + @extend .message.info +{% endcodeExample %} + +To fix this issue, avoid more confusion, and keep the implementation clean and +efficient the ability to extend compound selectors is unsupported in Dart Sass +and will be removed in a future version of LibSass. For compatibility, users +should extend each simple selector separately instead: + +{% codeExample 'extend-compound-good' %} + .message { + border: 1px solid black; + } + .info { + font-size: 1.5rem; + } + + .heads-up { + @extend .message, .info; + } + === + .message + border: 1px solid black + + .info + font-size: 1.5rem + + + .heads-up + @extend .message, .info +{% endcodeExample %} + +{% headsUp %} + Because Sass doesn't know the details of the HTML the CSS is going to style, + any `@extend` might need to generate extra selectors that won't apply to your + HTML in particular. This is especially true when switching away from extending + compound selectors. + + Most of the time, these extra selectors won't cause any problems, and will + only add a couple extra bytes to gzipped CSS. But some stylesheets might be + relying more heavily on the old behavior. In that case, we recommend replacing + the compound selector with a [placeholder selector][]. + + [placeholder selector]: /documentation/style-rules/placeholder-selectors + + {% codeExample 'extend-compound-heads-up' %} + // Instead of just `.message.info`. + %message-info, .message.info { + border: 1px solid black; + font-size: 1.5rem; + } + + .heads-up { + // Instead of `.message.info`. + @extend %message-info; + } + === + // Instead of just `.message.info`. + %message-info, .message.info + border: 1px solid black + font-size: 1.5rem + + + .heads-up + // Instead of `.message.info`. + @extend %message-info + {% endcodeExample %} +{% endheadsUp %} diff --git a/source/documentation/breaking-changes/function-units.liquid b/source/documentation/breaking-changes/function-units.liquid deleted file mode 100644 index ed26269..0000000 --- a/source/documentation/breaking-changes/function-units.liquid +++ /dev/null @@ -1,215 +0,0 @@ ---- -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. ---- - -{% markdown %} - ## Hue - - {% compatibility 'dart: "1.32.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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. - - [angle unit]: https://drafts.csswg.org/css-values-4/#angles - - To fix this issue and bring Sass in line with the CSS spec, we're making - changes in multiple phases: - - ### Phase 1{#hue-phase-1} - - {% compatibility 'dart: "1.32.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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 is - still allowed. - - ### Phase 2{#hue-phase-2} - - {% compatibility 'dart: "1.52.1"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#hue-phase-3} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#saturation-lightness-phase-1} - - {% compatibility 'dart: "1.32.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - Currently, Sass just emits a deprecation warning if you pass a number with no - unit or a unit other than `%` as a lightness or saturation to any function. - - ### Phase 2{#saturation-lightness-phase-2} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#alpha-phase-1} - - {% compatibility 'dart: "1.56.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#alpha-phase-2} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#alpha-phase-3} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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]: /documentation/modules/math#random -{% endmarkdown %} - -{% codeExample 'function-units', false %} - // Future Sass, doesn't work yet! - @debug math.random(100px); // 42px - === - // Future Sass, doesn't work yet! - @debug math.random(100px) // 42px -{% endcodeExample %} - -{% markdown %} - ### Phase 1{#math-random-phase-1} - - {% compatibility 'dart: "1.54.5"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - Currently, Sass emits a deprecation warning if you pass a `$limit` with units - to `math.random()`. - - ### Phase 2{#math-random-phase-2} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - In Dart Sass 2.0.0, passing a `$limit` number with units will be an error. - - ### Phase 3{#math-random-phase-3} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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]: /documentation/modules/color#mix - [`color.invert()` function]: /documentation/modules/color#invert - - ### Phase 1{#weight-phase-1} - - {% compatibility 'dart: "1.56.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#weight-phase-2} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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]: /documentation/modules/list#nth - [`list.set-nth()` function]: /documentation/modules/list#set-nth - - ### Phase 1{#index-phase-1} - - {% compatibility 'dart: "1.56.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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{#index-phase-2} - - {% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - 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. -{% endmarkdown %} diff --git a/source/documentation/breaking-changes/function-units.md b/source/documentation/breaking-changes/function-units.md new file mode 100644 index 0000000..cbf62fb --- /dev/null +++ b/source/documentation/breaking-changes/function-units.md @@ -0,0 +1,209 @@ +--- +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 + +{% compatibility 'dart: "1.32.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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. + +[angle unit]: https://drafts.csswg.org/css-values-4/#angles + +To fix this issue and bring Sass in line with the CSS spec, we're making changes +in multiple phases: + +### Phase 1 + +{% compatibility 'dart: "1.32.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 is +still allowed. + +### Phase 2 + +{% compatibility 'dart: "1.52.1"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: "1.32.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +Currently, Sass just emits a deprecation warning if you pass a number with no +unit or a unit other than `%` as a lightness or saturation to any function. + +### Phase 2 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: "1.56.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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]: /documentation/modules/math#random + +{% codeExample 'function-units', false %} + // Future Sass, doesn't work yet! + @debug math.random(100px); // 42px + === + // Future Sass, doesn't work yet! + @debug math.random(100px) // 42px +{% endcodeExample %} + +### Phase 1 + +{% compatibility 'dart: "1.54.5"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +Currently, Sass emits a deprecation warning if you pass a `$limit` with units to +`math.random()`. + +### Phase 2 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +In Dart Sass 2.0.0, passing a `$limit` number with units will be an error. + +### Phase 3 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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]: /documentation/modules/color#mix +[`color.invert()` function]: /documentation/modules/color#invert + +### Phase 1 + +{% compatibility 'dart: "1.56.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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]: /documentation/modules/list#nth +[`list.set-nth()` function]: /documentation/modules/list#set-nth + +### Phase 1 + +{% compatibility 'dart: "1.56.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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 + +{% compatibility 'dart: false', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +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/moz-document.liquid b/source/documentation/breaking-changes/moz-document.liquid deleted file mode 100644 index c01df11..0000000 --- a/source/documentation/breaking-changes/moz-document.liquid +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: 'Breaking Change: -moz-document' -introduction: > - Firefox used to have a @-moz-document rule requiring special parsing. As - support is removed from Firefox, Sass is in the process of removing support - for parsing them. ---- - -{% markdown %} - Sass has historically supported a special parsing for the `@-moz-document` - rule. As [Firefox dropped support for them], Sass will also drop support for - the special parsing and will treat it as an unknown at-rule. - - [Firefox dropped support for them]: https://web.archive.org/web/20200528221656/https://www.fxsitecompat.dev/en-CA/docs/2018/moz-document-support-has-been-dropped-except-for-empty-url-prefix/ - - **There is one exception**: an empty url prefix function is still allowed, as - that's used in a hack targetting Firefox. -{% endmarkdown %} - -{% codeExample 'moz-document' %} - @-moz-document url-prefix() { - .error { - color: red; - } - } - === - @-moz-document url-prefix() - .error - color: red -{% endcodeExample %} - -{% markdown %} - ## Transition Period - - {% compatibility 'dart: "1.7.2"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - First, we'll emit deprecation warnings for all usages of `@-moz-document` - except for the empty url-prefix hack. - - In Dart Sass 2.0, `@-moz-document` will be treated as an unknown at-rule. -{% endmarkdown %} diff --git a/source/documentation/breaking-changes/moz-document.md b/source/documentation/breaking-changes/moz-document.md new file mode 100644 index 0000000..8b6fa16 --- /dev/null +++ b/source/documentation/breaking-changes/moz-document.md @@ -0,0 +1,37 @@ +--- +title: 'Breaking Change: -moz-document' +introduction: > + Firefox used to have a @-moz-document rule requiring special parsing. As + support is removed from Firefox, Sass is in the process of removing support + for parsing them. +--- + +Sass has historically supported a special parsing for the `@-moz-document` rule. +As [Firefox dropped support for them], Sass will also drop support for the +special parsing and will treat it as an unknown at-rule. + +[Firefox dropped support for them]: https://web.archive.org/web/20200528221656/https://www.fxsitecompat.dev/en-CA/docs/2018/moz-document-support-has-been-dropped-except-for-empty-url-prefix/ + +**There is one exception**: an empty url prefix function is still allowed, as +that's used in a hack targetting Firefox. + +{% codeExample 'moz-document' %} + @-moz-document url-prefix() { + .error { + color: red; + } + } + === + @-moz-document url-prefix() + .error + color: red +{% endcodeExample %} + +## Transition Period + +{% compatibility 'dart: "1.7.2"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +First, we'll emit deprecation warnings for all usages of `@-moz-document` except +for the empty url-prefix hack. + +In Dart Sass 2.0, `@-moz-document` will be treated as an unknown at-rule. diff --git a/source/documentation/breaking-changes/slash-div.liquid b/source/documentation/breaking-changes/slash-div.liquid deleted file mode 100644 index c6d359c..0000000 --- a/source/documentation/breaking-changes/slash-div.liquid +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: 'Breaking Change: Slash as Division' -introduction: > - Sass currently treats `/` as a division operation in some contexts and a - separator in others. This makes it difficult for Sass users to tell what any - given `/` will mean, and makes it hard to work with new CSS features that use - `/` as a separator. ---- - -{% compatibility 'dart: "partial"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - -{% markdown %} - Today, Sass uses [complex heuristics][] to figure out whether a `/` should be - treated as division or a separator. Even then, as a separator it just produces - an unquoted string that's difficult to inspect from within Sass. As more and - more CSS features like [CSS Grid][] and the [new `rgb()` and `hsl()` syntax][] - use `/` as a separator, this is becoming more and more painful to Sass users. - - [complex heuristics]: /documentation/operators/numeric#slash-separated-values - [CSS Grid]: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row - [new `rgb()` and `hsl()` syntax]: https://drafts.csswg.org/css-color/#rgb-functions - - Because Sass is a CSS superset, we're matching CSS's syntax by redefining `/` - to be *only* a separator. `/` will be treated as a new type of list separator, - similar to how `,` works today. Division will instead be written using the new - `math.div()` function. This function will behave exactly the same as `/` does - today. - - This deprecation does not affect uses of `/` inside `calc()` expressions. -{% endmarkdown %} - -{% codeExample 'slash-div' %} - @use "sass:math"; - - // Future Sass, doesn't work yet! - .item3 { - $row: span math.div(6, 2) / 7; // A two-element slash-separated list. - grid-row: $row; - } - === - @use "sass:math" - - // Future Sass, doesn't work yet! - .item3 - $row: span math.div(6, 2) / 7 // A two-element slash-separated list. - grid-row: $row - === - .item3 { - grid-row: span 3 / 7; - } -{% endcodeExample %} - -{% markdown %} - ## Transition Period - - {% compatibility 'dart: "1.33.0"', 'libsass: false', 'ruby: false', 'feature: "math.div() and list.slash()"' %}{% endcompatibility %} - - To ease the transition, we've begun by adding the `math.div()` function. The - `/` operator still does division for now, but it also prints a deprecation - warning when it does so. Users should switch all division to use `math.div()` - instead. -{% endmarkdown %} - -{% render 'doc_snippets/silence-deprecations' %} - -{% codeExample 'math-div', false %} - @use "sass:math"; - - // WRONG, will not work in future Sass versions. - @debug (12px/4px); // 3 - - // RIGHT, will work in future Sass versions. - @debug math.div(12px, 4px); // 3 - === - @use "sass:math" - - // WRONG, will not work in future Sass versions. - @debug (12px/4px) // 3 - - // RIGHT, will work in future Sass versions. - @debug math.div(12px, 4px) // 3 -{% endcodeExample %} - -{% markdown %} - Slash-separated lists will also be available in the transition period. Because - they can't be created with `/` yet, the `list.slash()` function will be added - to create them. You will also be able to pass `"slash"` as the `$separator` to - the [`list.join()` function][] and the [`list.append()` function][]. - - [`list.join()` function]: /documentation/modules/list#join - [`list.append()` function]: /documentation/modules/list#append -{% endmarkdown %} - -{% codeExample 'slash-div-list' %} - @use "sass:list"; - @use "sass:math"; - - .item3 { - $row: list.slash(span math.div(6, 2), 7); - grid-row: $row; - } - === - @use "sass:list" - @use "sass:math" - - .item3 - $row: list.slash(span math.div(6, 2), 7) - grid-row: $row - === - .item3 { - grid-row: span 3 / 7; - } -{% endcodeExample %} - -{% compatibility 'dart: "1.40.0"', 'libsass: false', 'ruby: false', 'feature: "First-class calc"' %}{% endcompatibility %} - -{% markdown %} - Alternatively, users can wrap division operations inside a `calc()` - expression, which Sass will simplify to a single number. -{% endmarkdown %} - -{% codeExample 'slash-div-calc', false %} - // WRONG, will not work in future Sass versions. - @debug (12px/4px); // 3 - - // RIGHT, will work in future Sass versions. - @debug calc(12px / 4px); // 3 - === - // WRONG, will not work in future Sass versions. - @debug (12px/4px) // 3 - - // RIGHT, will work in future Sass versions. - @debug calc(12px / 4px) // 3 -{% endcodeExample %} - -{% markdown %} - ## Automatic Migration - - You can use [the Sass migrator][] to automatically update your stylesheets to - use `math.div()` and `list.slash()`. - - [the Sass migrator]: https://github.com/sass/migrator#readme - - ```shellsession - $ npm install -g sass-migrator - $ sass-migrator division **/*.scss - ``` -{% endmarkdown %} diff --git a/source/documentation/breaking-changes/slash-div.md b/source/documentation/breaking-changes/slash-div.md new file mode 100644 index 0000000..659c813 --- /dev/null +++ b/source/documentation/breaking-changes/slash-div.md @@ -0,0 +1,133 @@ +--- +title: 'Breaking Change: Slash as Division' +introduction: > + Sass currently treats `/` as a division operation in some contexts and a + separator in others. This makes it difficult for Sass users to tell what any + given `/` will mean, and makes it hard to work with new CSS features that use + `/` as a separator. +--- + +{% compatibility 'dart: "partial"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +Today, Sass uses [complex heuristics][] to figure out whether a `/` should be +treated as division or a separator. Even then, as a separator it just produces +an unquoted string that's difficult to inspect from within Sass. As more and +more CSS features like [CSS Grid][] and the [new `rgb()` and `hsl()` syntax][] +use `/` as a separator, this is becoming more and more painful to Sass users. + +[complex heuristics]: /documentation/operators/numeric#slash-separated-values +[CSS Grid]: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row +[new `rgb()` and `hsl()` syntax]: https://drafts.csswg.org/css-color/#rgb-functions + +Because Sass is a CSS superset, we're matching CSS's syntax by redefining `/` to +be *only* a separator. `/` will be treated as a new type of list separator, +similar to how `,` works today. Division will instead be written using the new +`math.div()` function. This function will behave exactly the same as `/` does +today. + +This deprecation does not affect uses of `/` inside `calc()` expressions. + +{% codeExample 'slash-div' %} + @use "sass:math"; + + // Future Sass, doesn't work yet! + .item3 { + $row: span math.div(6, 2) / 7; // A two-element slash-separated list. + grid-row: $row; + } + === + @use "sass:math" + + // Future Sass, doesn't work yet! + .item3 + $row: span math.div(6, 2) / 7 // A two-element slash-separated list. + grid-row: $row + === + .item3 { + grid-row: span 3 / 7; + } +{% endcodeExample %} + +## Transition Period + +{% compatibility 'dart: "1.33.0"', 'libsass: false', 'ruby: false', 'feature: "math.div() and list.slash()"' %}{% endcompatibility %} + +To ease the transition, we've begun by adding the `math.div()` function. The `/` +operator still does division for now, but it also prints a deprecation warning +when it does so. Users should switch all division to use `math.div()` instead. + +{% render 'doc_snippets/silence-deprecations' %} + +{% codeExample 'math-div', false %} + @use "sass:math"; + + // WRONG, will not work in future Sass versions. + @debug (12px/4px); // 3 + + // RIGHT, will work in future Sass versions. + @debug math.div(12px, 4px); // 3 + === + @use "sass:math" + + // WRONG, will not work in future Sass versions. + @debug (12px/4px) // 3 + + // RIGHT, will work in future Sass versions. + @debug math.div(12px, 4px) // 3 +{% endcodeExample %} + +Slash-separated lists will also be available in the transition period. Because +they can't be created with `/` yet, the `list.slash()` function will be added to +create them. You will also be able to pass `"slash"` as the `$separator` to the +[`list.join()` function][] and the [`list.append()` function][]. + +[`list.join()` function]: /documentation/modules/list#join +[`list.append()` function]: /documentation/modules/list#append + +{% codeExample 'slash-div-list' %} + @use "sass:list"; + @use "sass:math"; + + .item3 { + $row: list.slash(span math.div(6, 2), 7); + grid-row: $row; + } + === + @use "sass:list" + @use "sass:math" + + .item3 + $row: list.slash(span math.div(6, 2), 7) + grid-row: $row +{% endcodeExample %} + +{% compatibility 'dart: "1.40.0"', 'libsass: false', 'ruby: false', 'feature: "First-class calc"' %}{% endcompatibility %} + +Alternatively, users can wrap division operations inside a `calc()` expression, +which Sass will simplify to a single number. + +{% codeExample 'slash-div-calc', false %} + // WRONG, will not work in future Sass versions. + @debug (12px/4px); // 3 + + // RIGHT, will work in future Sass versions. + @debug calc(12px / 4px); // 3 + === + // WRONG, will not work in future Sass versions. + @debug (12px/4px) // 3 + + // RIGHT, will work in future Sass versions. + @debug calc(12px / 4px) // 3 +{% endcodeExample %} + +## Automatic Migration + +You can use [the Sass migrator][] to automatically update your stylesheets to +use `math.div()` and `list.slash()`. + +[the Sass migrator]: https://github.com/sass/migrator#readme + +```shellsession +$ npm install -g sass-migrator +$ sass-migrator division **/*.scss +``` diff --git a/source/documentation/breaking-changes/strict-unary.liquid b/source/documentation/breaking-changes/strict-unary.liquid deleted file mode 100644 index 8776734..0000000 --- a/source/documentation/breaking-changes/strict-unary.liquid +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: 'Breaking Change: Strict Unary Operators' -introduction: > - Sass has historically allowed `-` and `+` to be used in ways that make it - ambiguous whether the author intended them to be a binary or unary operator. - This confusing syntax is being deprecated. ---- - -{% markdown %} - How is this property compiled? -{% endmarkdown %} - -{% codeExample 'strict-unary', false %} - $size: 10px; - - div { - margin: 15px -$size; - } - === - $size: 10px - - div - margin: 15px -$size -{% endcodeExample %} - -{% markdown %} - Some users might say "the `-` is attached to `$size`, so it should be `margin: - 20px -10px`". Others might say "the `-` is between `20px` and `$size`, so it - should be `margin: 5px`." Sass currently agrees with the latter opinion, but - the real problem is that it's so confusing in the first place! This is a - natural but unfortunate consequence of CSS's space-separated list syntax - combined with Sass's arithmetic syntax. - - That's why we're moving to make this an error. In the future, if you want to - use a binary `-` or `+` operator (that is, one that subtracts or adds two - numbers), you'll need to put whitespace on both sides or on neither side: - - * Valid: `15px - $size` - * Valid: `(15px)-$size` - * Invalid: `15px -$size` - - If you want to use a unary `-` or `+` operator as part of a space-separated - list, you'll (still) need to wrap it in parentheses: - - * Valid: `15px (-$size)` - - ## Transition Period - - {% compatibility 'dart: "1.55.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} - - We'll make this an error in Dart Sass 2.0.0, but until then it'll just emit a - deprecation warning. - - {% render 'doc_snippets/silence-deprecations' %} - - ## Automatic Migration - - You can use [the Sass migrator] to automatically update your stylesheets to - add a space after any `-` or `+` operators that need it, which will preserve - the existing behavior of these stylesheets. - - [the Sass migrator]: https://github.com/sass/migrator#readme - - ```shellsession - $ npm install -g sass-migrator - $ sass-migrator strict-unary **/*.scss - ``` -{% endmarkdown %} diff --git a/source/documentation/breaking-changes/strict-unary.md b/source/documentation/breaking-changes/strict-unary.md new file mode 100644 index 0000000..2c141d9 --- /dev/null +++ b/source/documentation/breaking-changes/strict-unary.md @@ -0,0 +1,64 @@ +--- +title: 'Breaking Change: Strict Unary Operators' +introduction: > + Sass has historically allowed `-` and `+` to be used in ways that make it + ambiguous whether the author intended them to be a binary or unary operator. + This confusing syntax is being deprecated. +--- + +How is this property compiled? + +{% codeExample 'strict-unary', false %} + $size: 10px; + + div { + margin: 15px -$size; + } + === + $size: 10px + + div + margin: 15px -$size +{% endcodeExample %} + +Some users might say "the `-` is attached to `$size`, so it should be `margin: +20px -10px`". Others might say "the `-` is between `20px` and `$size`, so it +should be `margin: 5px`." Sass currently agrees with the latter opinion, but the +real problem is that it's so confusing in the first place! This is a natural but +unfortunate consequence of CSS's space-separated list syntax combined with +Sass's arithmetic syntax. + +That's why we're moving to make this an error. In the future, if you want to use +a binary `-` or `+` operator (that is, one that subtracts or adds two numbers), +you'll need to put whitespace on both sides or on neither side: + +* Valid: `15px - $size` +* Valid: `(15px)-$size` +* Invalid: `15px -$size` + +If you want to use a unary `-` or `+` operator as part of a space-separated +list, you'll (still) need to wrap it in parentheses: + +* Valid: `15px (-$size)` + +## Transition Period + +{% compatibility 'dart: "1.55.0"', 'libsass: false', 'ruby: false' %}{% endcompatibility %} + +We'll make this an error in Dart Sass 2.0.0, but until then it'll just emit a +deprecation warning. + +{% render 'doc_snippets/silence-deprecations' %} + +## Automatic Migration + +You can use [the Sass migrator] to automatically update your stylesheets to add +a space after any `-` or `+` operators that need it, which will preserve the +existing behavior of these stylesheets. + +[the Sass migrator]: https://github.com/sass/migrator#readme + +```shellsession +$ npm install -g sass-migrator +$ sass-migrator strict-unary **/*.scss +``` diff --git a/source/documentation/modules/index.liquid b/source/documentation/modules/index.liquid index 47c3e74..e650bb4 100644 --- a/source/documentation/modules/index.liquid +++ b/source/documentation/modules/index.liquid @@ -46,11 +46,6 @@ introduction: > $primary-color: #6b717f color: $primary-color border: 1px solid color.scale($primary-color, $lightness: 20%) - === - .button { - color: #6b717f; - border: 1px solid #878d9a; - } {% endcodeExample %} {% markdown %} diff --git a/source/documentation/style-rules/declarations.liquid b/source/documentation/style-rules/declarations.liquid index 997036a..a348e12 100644 --- a/source/documentation/style-rules/declarations.liquid +++ b/source/documentation/style-rules/declarations.liquid @@ -227,10 +227,5 @@ introduction: > :root --font-family-sans-serif: #{meta.inspect($font-family-sans-serif)} --font-family-monospace: #{meta.inspect($font-family-monospace)} - === - :root { - --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto; - --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas; - } {% endcodeExample %} {% endheadsUp %} diff --git a/source/documentation/syntax/special-functions.liquid b/source/documentation/syntax/special-functions.liquid index 76c8bc0..e473607 100644 --- a/source/documentation/syntax/special-functions.liquid +++ b/source/documentation/syntax/special-functions.liquid @@ -145,8 +145,4 @@ introduction: > .logo background: element(##{$logo-element}) - === - .logo { - background: element(#logo-bg); - } {% endcodeExample %} diff --git a/source/documentation/values/calculations.liquid b/source/documentation/values/calculations.liquid index e2ae88f..00d705a 100644 --- a/source/documentation/values/calculations.liquid +++ b/source/documentation/values/calculations.liquid @@ -84,11 +84,6 @@ introduction: > .sidebar width: $width padding-left: calc($width / 4) - === - .sidebar { - width: calc(400px + 10%); - padding-left: calc((400px + 10%) / 4); - } {% endcodeExample %} {% markdown %} diff --git a/source/documentation/variables.md b/source/documentation/variables.md index fb6499f..4ccf18e 100644 --- a/source/documentation/variables.md +++ b/source/documentation/variables.md @@ -324,9 +324,5 @@ global scope. .alert // Instead of $theme-color-#{warning} background-color: map.get($theme-colors, "warning") - === - .alert { - background-color: #ffc107; - } {% endcodeExample %} {% endheadsUp %} diff --git a/source/guide.md b/source/guide.md index 04a269c..2346288 100644 --- a/source/guide.md +++ b/source/guide.md @@ -436,19 +436,6 @@ to do some simple math to calculate widths for an `article` and `aside`. aside[role="complementary"] width: math.div(300px, 960px) * 100% margin-left: auto - === - .container { - display: flex; - } - - article[role="main"] { - width: 62.5%; - } - - aside[role="complementary"] { - width: 31.25%; - margin-left: auto; - } {% endcodeExample %} We've created a very simple fluid grid, based on 960px. Operations in Sass let