拥抱吉祥 發表於 2026-5-3 22:17:06

CSS中calc(100%-100px)不加空格不生效

<h3>问题起因</h3>
<p>在使用<code>calc</code>时发现无法生效,写法是:</p>
<div class="jb51code">
<pre class="brush:css;">
width: calc(100%-100px);</pre>
</div>
<p>页面无效果,加空格后就发现有效果了:</p>
<div class="jb51code">
<pre class="brush:css;">
width: calc(100% - 100px);</pre>
</div>
<p>这是为什么?</p>
<h3>calc是什么?</h3>
<p>css3 的计算属性,用于动态计算长度值。<code>calc</code>语法:</p>
<div class="jb51code">
<pre class="brush:css;">
calc(expression)      // expression 是数学表达式</pre>
</div>
<p>用法&amp;定义</p>
<ul>
    <li>运算符前后都需要保留一个空格,例如:<code>width: calc(100% - 100px)</code>;</li>
    <li>任何长度值都可以使用<code>calc()</code>函数进行计算;</li>
    <li><code>calc()</code> 函数支持 &quot;+&quot;, &quot;-&quot;, &quot;*&quot;, &quot;/&quot; 运算;</li>
    <li><code>calc()</code> 函数使用标准的数学运算优先级规则;</li>
</ul>
<h3>先了解一下CSS中基础语法和数据类型:</h3>
<p><a href="https://www.w3.org/TR/CSS2/syndata.html" rel="nofollow" target="_blank">https://www.w3.org/TR/CSS2/syndata.html</a></p>
<p>在文档的这里应该是这里的核心语法:</p>
<p style="text-align:center"><img alt="image.png" src="https://img.jbzj.com/file_images/article/202305/2023050516022520.png" /></p>
<div class="jb51code">
<pre class="brush: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* * ')'
            | '(' S* * ')' | '[' S* * ']'
            ] S*;
unused      : block | ATKEYWORD S* | ';' S* | CDO S* | CDC S*;</pre>
</div>
<p>DIMENSION语法在最上面:</p>
<div class="jb51code">
<pre class="brush:css;">
DIMENSION {num}{ident}</pre>
</div>
<p>num应该是数字,翻一下ident的定义:</p>
<p>在4.1.1第二段的开头</p>
<p style="text-align:center"><img alt="image.png" src="https://img.jbzj.com/file_images/article/202305/2023050516022521.png" /></p>
<div class="jb51code">
<pre class="brush:css;">
ident [-]?{nmstart}{nmchar}*</pre>
</div>
<p>nmstart和nmchar的分别有:</p>
<div class="jb51code">
<pre class="brush:css;">
nmstart |{nonascii}|{escape}
nmchar |{nonascii}|{escape}</pre>
</div>
<h3>解析calc(100%-100px)</h3>
<p>手动解析一下<code>calc(100%-100px)</code>。先过<code>DIMENSION</code>语法,{num}{ident}将其分割为num:100、<code>ident:%-100px</code>。</p>
<p>为什么是<code>%-100px</code>?</p>
<p>其实,应该是<code>%</code>和<code>-100px</code>,两个被作为单位解析。因为<code>-100px</code>符合nmchar语法,没有将其拆分。如果<code>-100px</code>有个空格,就会拆分为<code>-</code>和<code>100</code>以及<code>px</code>。但是这个例子,只能较好的解释为什么在<code>-</code>后面加空格。为什么前面也要加空格?</p>
<p>引出新的例子</p>
<p>在此,引出一个新的例子:</p>
<div class="jb51code">
<pre class="brush:css;">
width: calc(100px-100px);</pre>
</div>
<p>在编译时时,会将其直接拆分为<code>100</code>和<code>px-100px</code>,将<code>px-100px</code>过nmchar完全符合<code>\[\_a-z0-9-\]</code>。将其保留作为单位解析。但是<code>px-100px</code>不属于CSS中任何一个单位,也并无单位的定义。<br />
(这个案例,会更加好的解释,为什么<code>-</code>的前后都需要加空格。)<br />
如果<code>-</code>的前后有空格,就会被拆分为<code>100px</code>(数字100和单位px)、<code>-</code>、<code>100px</code>(数字100和单位px)来解析。</p>
<p><strong>源码为什么怎么写?</strong></p>
<p>为什么要把<code>-</code>放在里面?写成<code>calc(100% -100px)</code>或者<code>calc(100px -100px)</code>为什么不行?<br />
在这里,要引入一个正负数的概念,因为在数学标识符当中还有正号和负号这两个标识符。光看<code>calc(100% -100px)</code>和<code>calc(100px -100px)</code>的后半部分,<code>-100px</code>是不是更像是这里为<code>-100</code>和<code>px</code>。因为在CSS中是有负数的概念的,就像margin和padding中会常常用到负数。再引出一个新的例子:</p>
<div class="jb51code">
<pre class="brush:css;">
width: calc(500px - -100px);</pre>
</div>
<p><strong>再遇到这种情况怎么办?</strong></p>
<p>如果没有对于负号的定义应该就会<code>500px</code>、<code>-</code>、<code>-</code>、<code>100px</code>,两个减号怎么编译呢。在<code>-</code>的前后都加上空格,区别开减法和负号。</p>
<h3>参考资料</h3>
<p><a href="https://www.w3.org/TR/CSS2/syndata.html" rel="nofollow" target="_blank">https://www.w3.org/TR/CSS2/syndata.html</a></p>
頁: [1]
查看完整版本: CSS中calc(100%-100px)不加空格不生效