Stop using / as division
See original GitHub issueThe current plan:
- Create an automated migration tool that can migrate users from
/
-as-division to adivide()
function. - Deprecate
/
-as-division. Any time a/
would be interpreted unambiguously as division, or an ambiguous/
would be made unambiguous (for example by being stored in a variable), we produce a deprecation warning . - Add a top-level
divide()
function (math.div()
in the new module system). This will work exactly the same way division works today, with the obvious exception that it will never be treated as a slash separator. - Add a new slash-separated list type to represent slash as a separator. For the time being, this will not have a literal syntax.
- Add a
slash-list()
function (list.slash()
in the new module system) that returns a slash-separated list. Providing the ability to work with slash-separated lists even before they have a literal syntax will help stylesheets be forwards-compatible with the new wold. - Wait until at least three months after the module system is released.
- Release Dart Sass 2.0.0, which parses
/
as a list separator that binds more loosely than space but more tightly than comma. - Add support for first class
calc()
, which will allow/
-as-division in the form ofcalc(5px / 2)
. - Deprecate the
slash-list()
/list.slash()
function in favor of using the literal syntax. - Whenever Dart Sass 3.0.0 releases, remove
slash-list()
andlist.slash()
.
- Migrator
- Proposal
- Deprecation,
divide()
, andslash-list()
- Removal of /-as-division, deprecation of
slash-list()
- Removal of
slash-list()
The original issue:
When Sass was first designed, the most prominent use of /
as a separator in CSS was the short-form font
property, which used it to separate values for font-size
and line-height
. Because this was a relatively narrow edge case, we were able to use /
as the division operator as well, with some heuristics to decide between them. When /
was used as a separator, the value it produced was actually the divided number, but it was rendered with the slash instead.
However, the slash separator has been seeing more use in recent CSS specs. The grid-row
property uses it to separate values for grid-row-start
and grid-row-end
, and Colors Level 4 uses it in many color functions (including the new recommended syntax for rgb()
and hsl()
) to separate the alpha value from the rest of the parameters.
The increased prominence of this syntax means that the sharp edges of the heuristics we use to distinguish between /
-as-separator and /
-as-division will start cutting more users. Once Sass supports the new color function syntax (https://github.com/sass/sass/issues/2564), users are likely to try passing the alpha by variable, which will currently fail. We need to decide whether to do something about this, and if so, what.
How do we represent division?
Today, division is represented by the operator /
, which as discussed above is ambiguous. We could fairly easily add a new syntax for this, which would allow us to migrate users away from /
, eventually leaving it as unambiguously a separator.
I see a few options for this:
-
Keep the behavior as-is. This has the substantial benefit of requiring no migration, and it will be sufficient to support compatibility with plain CSS. However, it will make it much more painful for users to use dynamic alpha values for their colors as the new color function syntax gains traction.
-
Replace the
/
operator with another operator. There’s no option that’s really consistent with other programming languages, but~
is a possibility that’s currently unused and looks a little like ÷. https://github.com/sass/sass/issues/2565 -
Replace the
/
operator with a function, such asdiv()
. This is more verbose, but it’s very clear to the reader and it avoids any risk of further collision with new CSS syntax.
What is a slash separator?
If we do decide to free up /
to unambiguously represent a separator, we need to figure out how that separator works in terms of SassScript. This is particularly tricky because its scope varies from property to property. In font
, it’s tightly bound–the slash in italic small-caps bold 16px/2 cursive
separates 16px
from 2
, but it doesn’t separate italic small-caps bold 16px
from 2 cursive
. However, in grid-row
and the color functions, it’s loosely bound–the slash in rgb(1 2 3 / 0.5)
separates 1 2 3
from 0.5
, and is not bound to 3
in particular.
I think it makes sense in general to consider /
another kind of list separator, so that it works smoothly with existing APIs. But because of the scoping differences it’s not clear whether it should bind more tightly than space-separated lists or not. That is, should 1 2 / 3 4
be equivalent to (1 2) / (3 4)
or 1 (2 / 3) 4
?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:11
- Comments:91 (38 by maintainers)
Top GitHub Comments
//
is already the syntax for a single-line/silent comment.No need to “guess what” anybody here, we’re just talking and pitching in our points and opinions, if you come at people like that you’ll scare off valuable opinions 😉
I still think that doing math differently is a mistake, is not my decision to make, it’ll be what it’ll be, and people will use whatever they find the most comfortable and less painful.