CSS中calc(80vw - 100px)为什么不加空格会不生效?

问题起因

今天再使用calc时发现无法生效,我的写法是:

复制代码
  width: calc(100%-100px);

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

复制代码
  width: calc(100% - 100px);

有亿点疑惑,这是为什么?

calc是什么?

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

复制代码
calc(expression)//expression是数学表达式

用法&定义

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

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

文档链接》》

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

复制代码
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);

再遇到这种情况怎么办?

100'和'px'。因为在CSS中是有负数的概念的,就像margin和padding中会常常用到负数。再引出一个新的例子:

复制代码
 width: calc(500px - -100px);

再遇到这种情况怎么办?

如果没有对于负号的定义应该就会'500px'、'-'、'-'、'100px',两个减号怎么编译呢。所以在'-'的前后都加上空格,区别开减法和负号。

相关推荐
前端大卫几秒前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘16 分钟前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare17 分钟前
浅浅看一下设计模式
前端
Lee川21 分钟前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix1 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人1 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl1 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人1 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼1 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端