使用 CSS 数学函数

CSS 数学函数允许将属性值(例如元素的 heightanimation-durationfont-size)写成数学表达式。

在不使用任何数学函数的情况下,诸如 remvw% 等内置的CSS 单位通常已经足够灵活,可以为 HTML 元素设置样式以实现特定的用户体验。

然而,在某些情况下,我们可能会觉得使用单一的值和单位来表达元素的样式会受到限制。请思考以下示例:

  1. 我们希望将内容区域的高度设置为“视口高度减去导航栏高度”。
  2. 我们希望将两个元素的宽度相加,以定义第三个元素的宽度。
  3. 我们希望防止某些文本的可变 font-size 增长超过特定大小。

在所有这些情况下,我们都需要依靠数学来达到预期的结果。一种解决方案是依赖 JavaScript 定义的数学函数,并根据脚本计算的结果动态设置元素样式。

在许多情况下,包括上述示例,我们可以转而使用直接内置于 CSS 中的数学函数。与使用 JavaScript 相比,这种解决方案通常实现起来更简单,浏览器执行速度也更快。

总的来说,开发者可以在其样式表中使用近二十种 CSS 数学函数的组合。在本指南中,我们将举例说明四种较常用的函数,并介绍那些更高级的函数。

calc():基本数学运算

在我们上面三个示例的前两个中,我们希望根据加法或减法运算的结果来设置元素的样式。这正是 calc() 的用例之一。

calc() 函数允许你使用加法、减法、乘法和除法来指定 CSS 属性值。它通常用于组合两个具有不同单位的 CSS 值,例如 %px

calc() 数学函数接受一个数学表达式作为参数,并返回该表达式的结果,例如:

css
property: calc(expression);

calc() 示例

点击下面的播放图标,在代码演练场中查看 calc() 示例并亲自尝试。

css
div {
  background-color: black;
  margin: 4px 0;
  width: 100%;
}

div > code {
  display: block;
  background-color: red;
  color: white;
  height: 48px;
}

.calc1 > code {
  /* Output width: `110px` */
  width: calc(10px + 100px);
}

.calc2 > code {
  /* Output width: `10em` */
  width: calc(2em * 5);
}

.calc3 > code {
  /* Output width: Depends on the container's width */
  width: calc(100% - 32px);
}

.calc4 > code {
  --predefined-width: 100%;
  /* Output width: Depends on the container's width */
  width: calc(var(--predefined-width) - calc(16px * 2));
}

min():在一组值中找出最小值

在某些情况下,我们不希望 CSS 属性的值超过某个数字。举个例子,我们希望内容容器的宽度是“屏幕全宽”和“500 像素”中较小的一个。在这些情况下,我们可以使用 CSS 数学函数 min()

min() 数学函数接受一组逗号分隔的值作为参数,并返回这些值中最小的一个,例如:

css
width: min(32px, 50%, 2rem);

此函数通常用于比较两个具有不同单位的 CSS 值,例如 %px

min() 示例

点击下面的播放图标,在代码演练场中查看 min() 示例并亲自尝试。

css
div {
  background-color: black;
  margin: 4px 0;
  width: 100%;
}

div > code {
  display: block;
  background-color: darkblue;
  color: white;
  height: 48px;
}

.min1 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `50%` of the container's width */
  width: min(9999px, 50%);
}

.min2 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `100%` of the container's width */
  width: min(9999px, 100%);
}

.min3 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `120px` of the container's width */
  width: min(120px, 150px, 90%);
}

.min4 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `80px` of the container's width */
  width: min(80px, 90%);
}

max():在一组值中找出最大值

min() 类似,有时我们不希望 CSS 属性的值低于某个数字。例如,我们可能希望内容容器的宽度是“屏幕全宽”和“500 像素”中较大的一个。在这些情况下,我们可以使用 CSS 数学函数 max()

max() 数学函数接受一组逗号分隔的值作为参数,并返回这些值中最大的一个,例如:

css
width: max(32px, 50%, 2rem);

此函数通常用于比较两个具有不同单位的 CSS 值,例如 %px

请注意 min()max() 示例之间的异同。

max() 示例

点击下面的播放图标,在代码演练场中查看 max() 示例并亲自尝试。

css
div {
  background-color: black;
  margin: 4px 0;
  width: 100%;
  height: 48px;
}

div > code {
  display: block;
  background-color: darkmagenta;
  color: white;
  height: 48px;
}

.max1 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `50%` of the container's width */
  width: max(50px, 50%);
}

.max2 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `100%` of the container's width */
  width: max(50px, 100%);
}

.max3 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `90%` of the container's width */
  width: max(20px, 50px, 90%);
}

.max4 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `80%` of the container's width */
  width: max(80px, 80%);
}

clamp():将一个值限制在两个值之间

我们可以通过使用 clamp() 来结合 min()max() 的功能。clamp() 数学函数接受一个最小值、一个要限制的值和一个最大值作为参数,例如:

css
/* clamped value: 50%, minimum: 100px, maximum: 300px */
width: clamp(100px, 50%, 300px);
  • 如果要限制的值小于传入的最小值,函数将返回最小值。
  • 如果要限制的值大于传入的最大值,函数将返回最大值。
  • 如果要限制的值介于传入的最小值和最大值之间,函数将返回原始的要限制的值。

此函数通常用于比较两个具有不同单位的 CSS 值,例如 %px

clamp() 示例

点击下面的播放图标,在代码演练场中查看 clamp() 示例并亲自尝试。

css
div {
  background-color: black;
  margin: 4px 0;
  width: 100%;
  height: 48px;
}

div > code {
  display: block;
  background-color: darkgreen;
  color: white;
  height: 48px;
}

.clamp1 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `20%` of the container's width */
  width: clamp(20%, 1px, 80%);
}

.clamp2 > code {
  /* Output width: Depends on the container's width; */
  /* on this page, likely to be `90%` of the container's width */
  width: clamp(10%, 9999px, 90%);
}

.clamp3 > code {
  /* Output width: `125px` */
  width: clamp(125px, 1px, 250px);
}

.clamp4 > code {
  /* Output width: `150px` */
  width: clamp(25px, 9999px, 150px);
}

高级 CSS 数学函数

在布局和设计 DOM 元素样式时,四个基本的数学函数 calc()min()max()clamp() 通常就足够了。然而,对于高级用途,如数学学习材料、3D 可视化或 CSS 动画,你可以考虑使用:

  • 阶梯值函数
    • round():根据指定的取整策略计算一个值
    • mod():计算除法运算的余数,其符号与除数相同
    • rem():计算除法运算的余数,其符号与被除数相同
  • 三角函数
    • sin():计算一个数的三角正弦值
    • cos():计算一个数的三角余弦值
    • tan():计算一个数的三角正切值
    • asin():计算一个数的三角反正弦值
    • acos():计算一个数的三角反余弦值
    • atan():计算一个数的三角反正切值
    • atan2():根据给定的两个数计算三角反正切值
  • 指数函数
    • pow():计算一个数的指定次幂
    • sqrt():计算一个数的平方根
    • hypot():计算给定数值平方和的平方根
    • log():计算一个数的对数(默认底数为 e
    • exp():计算 e 的指定次幂
  • 符号函数
    • abs():计算一个数的绝对值
    • sign():计算一个数的符号(正、负或零)

总结

  • 你可以使用 CSS 数学函数来创建响应式用户界面,而无需编写任何 JavaScript 代码。
  • CSS 数学函数有时可以替代 CSS 媒体查询来定义布局断点。
  • 在 2023 年,Interop 项目的成员将“CSS 数学函数”选为一个重点改进领域。这意味着浏览器供应商正在共同努力,以确保 CSS 数学函数在不同浏览器和设备上表现一致。