<calc-keyword>

Baseline 广泛可用 *

此功能已成熟,可跨多个设备和浏览器版本使用。自 2022 年 12 月起,所有浏览器均已提供此功能。

* 此特性的某些部分可能存在不同级别的支持。

<calc-keyword> CSS 数据类型表示定义明确的常量,例如 epi。CSS 直接提供其中一些常量,以方便作者,而无需作者手动输入这些数学常量的多个数字或自行计算。

语法

<calc-keyword> 类型定义了可在 CSS 数学函数中使用的数字常量。

e

自然对数的底数,约等于 2.7182818284590452354

pi

圆的周长与直径之比,约等于 3.1415926535897932

infinity-infinity

无限值,用于表示最大/最小可能值。

NaN

表示“非数字”的规范大小写的值。

注意

calc() 内部参数的序列化遵循 IEEE-754 浮点数学标准,这意味着在处理 infinityNaN 等常量时需要注意一些情况。

  • 除以零将返回正无穷大或负无穷大,具体取决于分子的符号。

  • infinity 加、减或乘以任何值都将返回 infinity,除非它产生 NaN(见下文)。

  • 任何至少有一个 NaN 参数的运算都将返回 NaN。这意味着 0 / 0infinity / infinity0 * infinityinfinity + (-infinity)infinity - infinity 都将返回 NaN

  • 正负零是可能的值(0⁺0⁻)。这会产生以下影响:

    • 乘法或除法运算,如果产生零且恰好有一个负参数(-5 * 01 / (-infinity)),或者其他数学函数中的组合产生负结果,则将返回 0⁻
    • 0⁻ + 0⁻0⁻ - 0 将返回 0⁻。所有其他会产生零的加法或减法将返回 0⁺
    • 0⁻ 乘以或除以正数(包括 0⁺)将返回负结果(0⁻-infinity),而将 0⁻ 乘以或除以负数将返回正结果。

这些规则如何应用的示例显示在无穷大、NaN 和除以零部分。

注意:calc() 中使用 infinity 作为参数的情况很少见,但它可以用于避免硬编码的“魔术数字”或确保某个值始终大于另一个值。如果您需要明确表示某个属性具有该数据类型的“最大可能值”,这可能会很有用。

正式语法

<calc-keyword> = 
e |
pi |
infinity |
-infinity |
NaN

描述

数学常量只能在 CSS 数学函数内部用于计算。数学常量不是 CSS 关键字,但如果它们在计算之外使用,则它们会被视为任何其他关键字。例如:

  • animation-name: pi; 指的是名为“pi”的动画,而不是 pi 数字常量。
  • line-height: e; 无效,但 line-height: calc(e); 有效。
  • rotate(1rad * pi); 不起作用,因为 rotate() 不是数学函数。使用 rotate(calc(1rad * pi));

在数学函数中,<calc-keyword> 值被评估为 <number> 值,因此 epi 作为数字常量。

infinityNaN 略有不同,它们被视为退化的数字常量。虽然它们在技术上不是数字,但它们充当 <number> 值,因此要获得一个无限的 <length>,例如,需要一个像 calc(infinity * 1px) 这样的表达式。

包含 infinityNaN 值主要是为了使序列化更简单和更明显,但可以用于指示“最大可能值”,因为无限值会被钳制到允许的范围。这种情况很少合理,但当使用 infinity 时,它比在样式表中放置一个巨大的数字或硬编码魔术数字要简单得多。

NaN 外,所有常量均不区分大小写,因此 calc(Pi)calc(E)calc(InFiNiTy) 均有效。

e
-e
E
pi
-pi
Pi
infinity
-infinity
InFiNiTy
NaN

以下所有情况均无效:

nan
Nan
NAN

示例

calc() 中使用 e 和 pi

以下示例展示了如何在 calc() 中使用 e 以指数递增的角度旋转元素。第二个框展示了如何在 sin() 函数中使用 pi

html
<div id="wrapper">
  <div class="container">
    <div id="e"></div>
    <input type="range" min="0" max="7" step="0.01" value="0" id="e-slider" />
    <label for="e-slider">e:</label>
    <span id="e-value"></span>
  </div>
  <div class="container">
    <div id="pi"></div>
    <input type="range" min="0" max="1" step="0.01" value="0" id="pi-slider" />
    <label for="pi-slider">pi:</label>
    <span id="pi-value"></span>
  </div>
</div>
js
// sliders
const eInput = document.querySelector("#e-slider");
const piInput = document.querySelector("#pi-slider");
// spans for displaying values
const eValue = document.querySelector("#e-value");
const piValue = document.querySelector("#pi-value");

eInput.addEventListener("input", function () {
  e.style.transform = `rotate(calc(1deg * pow(${this.value}, e)))`;
  eValue.textContent = e.style.transform;
});

piInput.addEventListener("input", function () {
  pi.style.rotate = `calc(sin(${this.value} * pi) * 100deg)`;
  piValue.textContent = pi.style.rotate;
});

无穷大、NaN 和除以零

以下示例展示了除以零时 width 属性的计算值,以及在控制台中查看不同 calc() 常量进行序列化后的结果。

html
<div></div>
css
div {
  height: 50px;
  background-color: red;
  width: calc(1px / 0);
}
js
const div = document.querySelector("div");
console.log(div.offsetWidth); // 17895698 (infinity clamped to largest value for width)

function logSerializedWidth(value) {
  div.style.width = value;
  console.log(div.style.width);
}

logSerializedWidth("calc(1px / 0)"); // calc(infinity * 1px)
logSerializedWidth("calc(1px / -0)"); // calc(-infinity * 1px)

logSerializedWidth("calc(1px * -infinity * -infinity)"); // calc(infinity * 1px)
logSerializedWidth("calc(1px * -infinity * infinity)"); // calc(-infinity * 1px)

logSerializedWidth("calc(1px * (NaN + 1))"); // calc(NaN * 1px)

规范

规范
CSS 值和单位模块第 4 级
# typedef-calc-keyword

浏览器兼容性

另见