Breaking Change: Strict Function Units
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.
HueHue permalink
- Dart Sass
- since 1.32.0
- LibSass
- ✗
- Ruby Sass
- ✗
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 1Phase 1 permalink
- Dart Sass
- since 1.32.0
- LibSass
- ✗
- Ruby Sass
- ✗
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 2Phase 2 permalink
- Dart Sass
- since 1.52.1
- LibSass
- ✗
- Ruby Sass
- ✗
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.
Phase 3Phase 3 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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 LightnessSaturation and Lightness permalink
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 1Phase 1 permalink
- Dart Sass
- since 1.32.0
- LibSass
- ✗
- Ruby Sass
- ✗
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 2Phase 2 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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.
AlphaAlpha permalink
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 red
.
To fix this issue and bring Sass in line with the CSS spec, we’re making changes in three phases:
Phase 1Phase 1 permalink
- Dart Sass
- since 1.56.0
- LibSass
- ✗
- Ruby Sass
- ✗
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 2Phase 2 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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.
Phase 3Phase 3 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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()
math.random() permalink
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.
SCSS Syntax
@use "sass:math";
// Future Sass, doesn't work yet!
@debug math.random(100px); // 42px
Sass Syntax
@use "sass:math"
// Future Sass, doesn't work yet!
@debug math.random(100px) // 42px
Phase 1Phase 1 permalink
- Dart Sass
- since 1.54.5
- LibSass
- ✗
- Ruby Sass
- ✗
Currently, Sass emits a deprecation warning if you pass a $limit
with units to
math.random()
.
Phase 2Phase 2 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
In Dart Sass 2.0.0, passing a $limit
number with units will be an error.
Phase 3Phase 3 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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.
WeightWeight permalink
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 %
.
Phase 1Phase 1 permalink
- Dart Sass
- since 1.56.0
- LibSass
- ✗
- Ruby Sass
- ✗
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 2Phase 2 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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.
IndexIndex permalink
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.
Phase 1Phase 1 permalink
- Dart Sass
- since 1.56.0
- LibSass
- ✗
- Ruby Sass
- ✗
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 2Phase 2 permalink
- Dart Sass
- ✗
- LibSass
- ✗
- Ruby Sass
- ✗
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.
Can I Silence the Warnings?Can I Silence the Warnings? permalink
Sass provides a powerful suite of options for managing which deprecation warnings you see and when.
Terse and Verbose ModeTerse and Verbose Mode permalink
By default, Sass runs in terse mode, where it will only print each type of deprecation warning five times before it silences additional warnings. This helps ensure that users know when they need to be aware of an upcoming breaking change without creating an overwhelming amount of console noise.
If you run Sass in verbose mode instead, it will print every deprecation
warning it encounters. This can be useful for tracking the remaining work to be
done when fixing deprecations. You can enable verbose mode using
the --verbose
flag on the command line, or
the verbose
option in the JavaScript API.
⚠️ Heads up!
When running from the JS API, Sass doesn’t share any information across
compilations, so by default it’ll print five warnings for each stylesheet
that’s compiled. However, you can fix this by writing (or asking the author of
your favorite framework’s Sass plugin to write) a custom Logger
that only
prints five errors per deprecation and can be shared across multiple compilations.
Silencing Deprecations in DependenciesSilencing Deprecations in Dependencies permalink
Sometimes, your dependencies have deprecation warnings that you can’t do
anything about. You can silence deprecation warnings from dependencies while
still printing them for your app using
the --quiet-deps
flag on the command line, or
the quietDeps
option in the JavaScript API.
For the purposes of this flag, a "dependency" is any stylesheet that’s not just a series of relative loads from the entrypoint stylesheet. This means anything that comes from a load path, and most stylesheets loaded through custom importers.
Silencing Specific DeprecationsSilencing Specific Deprecations permalink
If you know that one particular deprecation isn’t a problem for you, you can
silence warnings for that specific deprecation using
the --silence-deprecation
flag on the command line, or
the silenceDeprecations
option in the JavaScript API.