Как работает calc(), когда он содержит проценты?

Недавно я прибегал к неожиданному поведению при разработке макета сайта. Я был удивлен, обнаружив, что поведение calc(), по-видимому, полностью меняется в зависимости от того, существует ли единица процента на основе внутри аргумента.

Вот минимальное воспроизведение.

.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>

Ответы

Ответ 1

спецификации для calc явно говорят, что он не был полностью разрешен в это время:

Если проценты не разрешены при вычисленном значении, они не являются разрешены в выражениях calc(), например. 'Calc (100% - 100% + 1em) разрешает 'calc (0% + 1em), а не' calc (1em). Если есть специальные правила вычисления процентных значений в значении (например, "высота" свойство), они применяются всякий раз, когда выражение 'calc() содержит проценты.

Я бы предположительно предположил, что 10.2:

Если ширина используемого блока зависит от этой ширины элемента, то результирующий макет будет undefined в CSS 2.1.

применяется здесь, так как присутствует процент, так же как и для width:150% для внутреннего блока, внешний блок использует сжатие для соответствия.