CSS

问题起因

在使用calc时发现无法生效,写法是:

  1. width: calc(100%-100px);

页面无效果,加空格后就发现有效果了:

  1. width: calc(100% - 100px);

这是为什么?

calc是什么?

css3 的计算属性,用于动态计算长度值。calc语法:

  1. calc(expression) // expression 是数学表达式

用法&定义

  • 运算符前后都需要保留一个空格,例如:width: calc(100% - 100px)
  • 任何长度值都可以使用calc()函数进行计算;
  • calc() 函数支持 “+”, “-“, “*”, “/“ 运算;
  • calc() 函数使用标准的数学运算优先级规则;

    先了解一下CSS中基础语法和数据类型:

    https://www.w3.org/TR/CSS2/syndata.html

    在文档的这里应该是这里的核心语法:

    image.png
    1. stylesheet : [ CDO | CDC | S | statement ]*;
    2. statement : ruleset | at-rule;
    3. at-rule : ATKEYWORD S* any* [ block | ';' S* ];
    4. block : '{' S* [ any | block | ATKEYWORD S* | ';' S* ]* '}' S*;
    5. ruleset : selector? '{' S* declaration? [ ';' S* declaration? ]* '}' S*;
    6. selector : any+;
    7. declaration : property S* ':' S* value;
    8. property : IDENT;
    9. value : [ any | block | ATKEYWORD S* ]+;
    10. any : [ IDENT | NUMBER | PERCENTAGE | DIMENSION | STRING
    11. | DELIM | URI | HASH | UNICODE-RANGE | INCLUDES
    12. | DASHMATCH | ':' | FUNCTION S* [any|unused]* ')'
    13. | '(' S* [any|unused]* ')' | '[' S* [any|unused]* ']'
    14. ] S*;
    15. unused : block | ATKEYWORD S* | ';' S* | CDO S* | CDC S*;

    DIMENSION语法在最上面:

    1. DIMENSION {num}{ident}

    num应该是数字,翻一下ident的定义:

    在4.1.1第二段的开头
    image.png
    1. ident [-]?{nmstart}{nmchar}*

    nmstart和nmchar的分别有:

    ```css nmstart [_a-z]|{nonascii}|{escape}

nmchar [_a-z0-9-]|{nonascii}|{escape}

  1. <a name="dJ1Hu"></a>
  2. ## 解析`calc(100%-100px)`
  3. 手动解析一下`calc(100%-100px)`。先过`DIMENSION`语法,{num}{ident}将其分割为num:100、`ident:%-100px`。
  4. <a name="b7uid"></a>
  5. ### 为什么是`%-100px`?
  6. 其实,应该是`%`和`-100px`,两个被作为单位解析。因为`-100px`符合nmchar语法,没有将其拆分。如果`-100px`有个空格,就会拆分为`-`和`100`以及`px`。但是这个例子,只能较好的解释为什么在`-`后面加空格。为什么前面也要加空格?
  7. <a name="w20fJ"></a>
  8. ### 引出新的例子
  9. 在此,引出一个新的例子:
  10. ```css
  11. width: calc(100px-100px);

在编译时时,会将其直接拆分为100px-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是不是更像是这里为-100px。因为在CSS中是有负数的概念的,就像margin和padding中会常常用到负数。再引出一个新的例子:

  1. width: calc(500px - -100px);

再遇到这种情况怎么办?
如果没有对于负号的定义应该就会500px--100px,两个减号怎么编译呢。在-的前后都加上空格,区别开减法和负号。

参考资料

https://www.w3.org/TR/CSS2/syndata.html