I recently ran into some unexpected behavior while designing a site layout. I was surprised to find that the behavior of calc()
seems to totally change depending whether there is a percentage based unit anywhere inside its argument.
Here is a minimal reproduction.
.container {
font-size: 30px;
display: inline-block;
border: solid purple .1em;
}
.inner {
border: solid orange .1em;
}
.inner.em { width: 3em; }
.inner.calc { width: calc(3em + 0%); }
<div class="container">
<div class="inner em">abc</div>
</div>
<hr>
<div class="container">
<div class="inner calc">abc</div>
</div>
The second one is surprising to me, because I would expect that calc(3em + 0%)
would be identical to 3em
. However, every browser I've tested exhibits this behavior. This behavior occurs with any percentage. 0%
is not special. Is this part of the css spec?
The calc() function takes a single expression as its parameter, with the expression's result used as the value. The expression can be any simple expression combining the following operators, using standard operator precedence rules: + Addition.
Syntax. The <percentage> data type consists of a <number> followed by the percentage sign ( % ). Optionally, it may be preceded by a single + or - sign, although negative values are not valid for all properties. As with all CSS dimensions, there is no space between the symbol and the number.
To use the calc() function in React:Set the style prop on the element. Pass the result of calling calc() as the value for a CSS property. The call to calc() should be wrapped in a string, e.g. 'calc(100% - 600px)' .
The specs for calc explicitly say that it's not resolved completely at that time:
Where percentages are not resolved at computed value, they are not resolved in ‘calc()’ expressions, e.g. ‘calc(100% - 100% + 1em)’ resolves to ‘calc(0% + 1em)’, not to ‘calc(1em)’. If there are special rules for computing percentages in a value (e.g. the ‘height’ property), they apply whenever a ‘calc()’ expression contains percentages.
I would tentatively speculate that 10.2:
If the containing block's width depends on this element's width, then the resulting layout is undefined in CSS 2.1.
applies here, since there is a percentage involved, so just as with a width:150%
for the inner block, the outer block uses shrink-to-fit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With