为什么不忽略具有非法值的 `calc()` 宽度?

Why is a `calc()` width with an illegal value not ignored?

受到的启发,我发现了这个有趣的现象

由于负宽度是非法的,因此应该被忽略,我希望像 width:-200px;width:calc(0% - 200px); 这样的样式属性没有效果。事实上,对于第一个它没有。但是,第二个不会被忽略:改为使用宽度 0。

看这个例子:

div {border:1px solid; background:lime;}

#badwidth {width:-200px;}

#badcalc {width:calc(0% - 200px);}
Div with bad width:
<div id="badwidth"> </div>

Div with bad calc:
<div id="badcalc"> </div>

如果宽度 属性 被忽略,div 将是它的全宽(就像上面那个一样)。但是,它折叠为 0(请参阅左侧的黑线;那是边框)。

作为参考,这里有一些其他的 divs,以证明 1) calc(0% - 200px) 本身不是错误,以及 2) 它们工作正常并且第一个片段是异常的.

div {border:1px solid; background:lime;}

#calc {margin-right:calc(0% - 200px);}
Plain div:
<div> </div>

With calc(0% - 200px) in a place where it's OK:
<div id="calc"> </div>

那么,为什么正常宽度和计算宽度的行为不同?
如果它只是一个浏览器,我会称之为错误。但是他们都以同样的方式对待这个!所以必须有一些我忽略的东西。什么?

calc 的评估和规则中的允许值不同,如您所见。根据规范 CSS Values and Units:

While some properties allow negative length values, this may complicate the formatting and there may be implementation-specific limits. If a negative length value is allowed but cannot be supported, it must be converted to the nearest value that can be supported.

在这种情况下,-200 向上舍入为 0,因为它是宽度支持的最接近值。

编辑

前面的部分还指出:

Properties may restrict the length value to some range. If the value is outside the allowed range, the declaration is invalid and must be ignored.

声明width: -200px时,这个值超出了可接受的范围,因此被忽略。但是,似乎 calc 检查发生之前评估 -200 ,并将其四舍五入到可接受的范围内,因此不会被忽略。

更新

感谢@CBroe reference to the spec on calc:

Parse-time range-checking of values is not performed within calc(), and therefore out-of-range values do not cause the declaration to become invalid. However, the used value resulting from an expression must be clamped to the range allowed in the target context.

Since widths smaller than 0px are not allowed, these three declarations are equivalent:

width: calc(5px - 10px);
width: calc(-5px);
width: 0px;

Note however that width: -5px is not equivalent to width: calc(-5px)! Out-of-range values outside calc() are synactically invalid, and cause the entire declaration to be dropped.