Why must a + or - be surrounded with whitespace from within the Calc() method?
CssCss CalcCss Problem Overview
Recently I've started using the calc(...) method within CSS. I quickly learned that code such as: width: calc(100%-2)
will not work, though adding white-space before and after the -
operator will fix the problem and the calc method will function properly.
After doing a bit of research I found multiple blog posts reference that the white-space is required and many have even pointed to the specification (CSS3 8.1.1) which states:
> In addition, whitespace is required on both sides of the + and - > operators. (The * and / operaters can be used without whitespace > around them.)
Now, clearly, the spec tells us that these operators must be wrapped in white-space, but why? I've read further within the spec (through sections 8.1.2-4) and if it's explained in these additional portions, I'm not understanding the reasoning.
In simple terms, could someone explain why it was specified that calc(100% - 1)
or even calc(100%/2)
is acceptable syntax but not calc(100%-1)
?
Css Solutions
Solution 1 - Css
The -
character is one of the allowed characters in CSS idents. Judging by the resolution given here, it seems they wanted to prevent syntactic ambiguities that could arise from using -
without whitespace, especially with keyword values such as min-content
(although AFAIK keyword values aren't yet allowed within calc()
— correct me if I'm wrong).
Not everyone agrees with this resolution, though.
Solution 2 - Css
The Mozilla Developer Network explains it quite well:
> Note: The +
and -
operators must always be surrounded by whitespace. The operand of calc(50% -8px)
for instance will be parsed as a percentage followed by a negative length, an invalid expression, while the operand of calc(50% - 8px)
is a percentage followed by a minus sign and a length. Even further, calc(8px + -50%)
is treated as a length followed by a plus sign and a negative percentage.
>
> The *
and /
operators do not require whitespace, but adding it for consistency is allowed, and recommended.
Solution 3 - Css
I think you should first consider how do CSSs identify a length. A length is defined as an optional sign followed by a module and an optional unit of measure (although many properties actually require it):
<CSSlength> := [<sign>]<module>[<unit>]
So, for example, valid CSS lengths are:
-3px
100em
+10pc
0
91
5%
Defining a length like this, the CSS engine parses the following:
calc(100% -1px);
as a length followed by another length. In this case it would be 100%
followed by -1px
, which doesn't make sense to calc()
at all. This is also explained in the relative MDN documentation page.
In order to put two lengths in relation you need to use a distinct operator, therefore, following the above logic, you'll need to use whitespaces:
calc(100% - 1px);