CSS中calc(100%-100px)为什么不加空格会不生效?
作者:狗比玩意
链接:https://juejin.cn/post/7055169229980434462
问题起因
今天再使用calc时发现无法生效,我的写法是:
width: calc(100%-100px);
页面无效果,加空格后就发现有效果了:
width: calc(100% - 100px);
有亿点疑惑,这是为什么?
calc是什么?
css3 的计算属性,用于动态计算长度值。calc语法:
calc(expression) // expression 是数学表达式
用法&定义
运算符前后都需要保留一个空格,例如: width: calc(100% - 100px)
;任何长度值都可以使用calc()函数进行计算; calc() 函数支持 "+", "-", "*", "/" 运算; calc() 函数使用标准的数学运算优先级规则;
先了解一下CSS中基础语法和数据类型:
文档链接[1]
在文档的这里应该是这里的核心语法:
stylesheet : [ CDO | CDC | S | statement ]*;
statement : ruleset | at-rule;
at-rule : ATKEYWORD S* any* [ block | ';' S* ];
block : '{' S* [ any | block | ATKEYWORD S* | ';' S* ]* '}' S*;
ruleset : selector? '{' S* declaration? [ ';' S* declaration? ]* '}' S*;
selector : any+;
declaration : property S* ':' S* value;
property : IDENT;
value : [ any | block | ATKEYWORD S* ]+;
any : [ IDENT | NUMBER | PERCENTAGE | DIMENSION | STRING
| DELIM | URI | HASH | UNICODE-RANGE | INCLUDES
| DASHMATCH | ':' | FUNCTION S* [any|unused]* ')'
| '(' S* [any|unused]* ')' | '[' S* [any|unused]* ']'
] S*;
unused : block | ATKEYWORD S* | ';' S* | CDO S* | CDC S*;
DIMENSION语法在最上面:
DIMENSION {num}{ident}
num应该是数字,翻一下ident的定义:
在4.1.1第二段的开头
ident [-]?{nmstart}{nmchar}*
nmstart和nmchar的分别有:
nmstart [_a-z]|{nonascii}|{escape}
nmchar [_a-z0-9-]|{nonascii}|{escape}
解析calc(100%-100px)
让我们来代替解析器,解析一下calc(100%-100px)。先过DIMENSION语法,{num}{ident}将其分割为num:100、ident:%-100px。
为什么是%-100px
?
其实,应该是%
和-100px
,两个被作为单位解析。(这是我之前写文章没有关注到,我当时把%记成了字母。)因为-100px
符合nmchar语法,没有将其拆分。如果-100px
有个空格,就会拆分为-
和100
以及px
。但是这个例子,只能较好的解释为什么在-
后面加空格。为什么前面也要加空格?
引出新的例子
在此,引出一个新的例子:
width: calc(100px-100px);
在编译时时,会将其直接拆分为100
和px-100px
,将px-100px
过nmchar完全符合\[\_a-z0-9-\]
。将其保留作为单位解析。但是px-100px
不属于CSS中任何一个单位,也并无单位的定义。
(这个案例,会更加好的解释,为什么-
的前后都需要加空格。)
如果-
的前后有空格,就会被拆分为100px
(数字100和单位px)、-
、100px
(数字100和单位px)来解析。
源码为什么怎么写?
为什么要把-
放在里面?我们写成calc(100% -100px)
或者calc(100px -100px)
为什么不行?
在这里,要引入一个正负数的概念,因为在数学标识符当中还有正号和负号这两个标识符。光看calc(100% -100px)
和calc(100px -100px)
的后半部分,-100px
是不是更像是这里为-100
和px
。因为在CSS中是有负数的概念的,就像margin和padding中会常常用到负数。再引出一个新的例子:
width: calc(500px - -100px);
再遇到这种情况怎么办?
如果没有对于负号的定义应该就会500px
、-
、-
、100px
,两个减号怎么编译呢。所以在-
的前后都加上空格,区别开减法和负号。(当然这属于个人理解,并非官方解释)
参考资料
https://www.w3.org/TR/CSS2/syndata.html: https://link.juejin.cn?target=https%3A%2F%2Fwww.w3.org%2FTR%2FCSS2%2Fsyndata.html
最后
如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:
点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)
欢迎加我微信「qianyu443033099」拉你进技术群,长期交流学习...
关注公众号「前端下午茶」,持续为你推送精选好文,也可以加我为好友,随时聊骚。