大家好,这里是大家的林语冰。坚持阅读,自律打卡,每天一次,进步一点。
免责声明
本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考。英文原味版请传送 The New CSS Math: pow(), sqrt(), and exponential friends。
本期共享的是 —— CSS 添加了一大坨新型的数学函数,用来补充旧版功能(比如 calc()
)。它们最终都表示一个数值,但它们工作方式的细微差别并非一目了然。截至 2024 年 2 月,这些 CSS 函数可以在最新的 Edge、Chrome、Safari 和 Firefox 浏览器中使用。
pow()
的基本原理
数学中的幂运算(power)允许我们指定一个数字与其自身相乘的次数。
现在 CSS 也可以,pow()
函数采用两个参数:我们的初始数字和要应用的指数值。
line-height: pow(3, 1); /* 3 */
line-height: pow(3, 2); /* 9 */
line-height: pow(3, 3); /* 27 */
这对应 JS 由来已久的 Math.pow()
提供的功能。
console.log(Math.pow(3, 1)) // 3 ** 1= 3
console.log(Math.pow(3, 2)) // 3 ** 2 = 9
console.log(Math.pow(3, 3)) // 3 ** 3 = 27
与一大坨其他全新 CSS 数学函数不同,pow()
能且仅能支持原始数字。换而言之,我们无法在函数内部应用单位,为了获取单位,我们需要将 pow()
与 calc()
结合使用。
font-size: calc(1rem * pow(3, 2)); /* 1rem * 9 = 9rem */
rotate: calc(10deg * pow(3, 2)); /* 10deg * 9 = 90deg */
求根的基本原理
类似于 JS 的 Math.sqrt()
,CSS 中现在也有 sqrt()
来求数字的平方根。Math.sqrt()
需要一个参数,与 pow()
一样,它能且仅能支持数字,不适用于长度、百分比和其他具有单位的类型。
line-height: sqrt(1); /* 1 */
line-height: sqrt(4); /* 2 */
line-height: sqrt(9); /* 3 */
如果我们想求非平方根,比如立方根等,我们仍然需要使用 pow()
。如果使用分数作为指数,我们就会得到根,比如立方根的指数是 1/3
。
实际使用场景
与一大坨全新的数学函数一样,它们在日常工作中的使用场景并非一目了然。
在 CSS 规范中,展示了一个使用 pow()
定义字体大小和模块化比例的示例。举个栗子,这样每个标题就可以与相同的根大小相关。虽然此处并非一定需要使用 pow()
,因为也可以计算值然后粘贴进去,但由于展示 pow()
时的编程意图更清晰,因此有助于维护可读性。
<html>
<head>
<style>
h1,
h2,
h3 {
font-size: calc(1rem * pow(1.5, var(--heading-exponent)));
}
h1 {
--heading-exponent: 4;
}
h2 {
--heading-exponent: 3;
}
h3 {
--heading-exponent: 2;
}
</style>
</head>
<body>
<h1>一级标题</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>
</body>
</html>
或者我们可以跳出思维的框架。结合 @property
和自定义属性,我们可以创建一个感觉像是有缓动的线性动画。换而言之,动画应该随着时间的推移均匀地进行,但是通过使用指数,我们的动画感觉像是开始缓慢然后加速。
我们可以使用线性计时函数将变量从 1
动画化到 10
。然后我们将该变量应用为旋转或平移等某些变换的 pow()
的指数。动画会从 1
到 10
均匀分布,但变换的值会呈指数增长,从而加快产生的视觉运动。
<html>
<head>
<style>
.demo {
animation: power-of-love 10000ms infinite alternate linear;
transform: translateX(calc(var(--exponent, 0) * 9.25vw - 45vw));
}
.pow {
transform: translateX(
calc(pow(var(--value, 2), var(--exponent, 0)) * 0.05vw - 45vw)
);
}
@keyframes power-of-love {
0% {
--exponent: 0;
}
100% {
--exponent: 11;
}
}
.demo {
margin: auto;
font-size: calc(1rem);
width: 30vmin;
height: 30vmin;
border: 1.2vmin solid hsl(343 100% 50%);
border-right-color: hsl(173 100% 50%);
border-bottom-color: hsl(43 100% 50%);
border-left-color: hsl(283 100% 50%);
background-color: hsl(343 100% 50% / 0.12);
display: grid;
place-items: center;
z-index: -1;
}
@property --exponent {
syntax: '<number>';
inherits: false;
initial-value: 1;
}
body {
display: flex;
flex-direction: column;
min-height: 100vh;
background: #16161c;
color: #fbfbf8;
font-family: system-ui, sans-serif;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div class="demo">reference</div>
<div class="demo pow">pow()</div>
<script>
if (
window?.CSS?.supports('opacity: pow(2,2)') &&
window?.CSS?.registerProperty !== undefined
) {
document.documentElement.classList.add('supported')
}
</script>
</body>
</html>
其他指数函数
还有其他三个与指数相关的函数需要了解。
e
作为 exp()
的幂
exp()
函数采用一个参数,表示应用于数学常数 e
的指数。所以 exp(3)
相当于 pow(e, 3)
,并且像 pow()
一样,它也不允许单位。这与 JS 中的 Math.exp()
类似。
log()
对数
相关地,log()
采用两个参数,第二个参数是可选的,并用来表示对数。
在 JS 中,Math.log
有且仅有一个参数,它表示作为参数传递的数字的自然对数。该对数的底是 e
。
CSS 为 log()
添加的第二个可选参数允许我们把基数 e
更改为新数字。
opacity: log(2); /* 基数为 e 的 log 2 = .693147 */
opacity: log(2, 10); /* 基数为 10 的log 2 = .30103 */
JS 中没有第二个参数,因此 CSS 添加了基本更改,更方便使用。CSS log(number, base)
的等价物可以在 JS 中实现为 Math.log(number) / Math.log(base)
。
hypot()
求平方和的平方根
虽然字数很多,但这是一个有趣的、小众的功能。
在直角三角形的几何中,我们可以通过以下过程找到斜边(与直角相对的边)的长度:
- 求其余两条边的平方
- 将这些值加在一起
- 对上一步的总和求平方根
因此,使用 CSS 的 hypot()
函数,以及 JS 中的 Math.hypot()
方法,我们可以传入任意数量的参数。然后,该函数将计算所有参数的平方,将它们累加在一起,并取平方根。
animation-iteration-count: hypot(2); /* 2 */
animation-iteration-count: hypot(3, 4); /* 5 = sqrt(9 + 16) = sqrt(25) */
line-height: hypot(1, 2, 3, 4); /* ~5.4772 = sqrt(1 + 4 + 9 + 16) = sqrt(30) */
line-height: hypot(-2); /* 2 */
width: hypot(30px, 40px); /* 50px = sqrt(900px + 1600px) = sqrt(2500px) */
这是本文中讨论的唯一一个允许使用单位的函数,因为所有项目都属于同一类型。
本期话题是 —— 你最常用的 CSS 函数是哪一个,有什么奇技淫巧?
欢迎在本文下方群聊自由言论,文明共享。谢谢大家的点赞,掰掰~
《前端 9 点半》每日更新,坚持阅读,自律打卡,每天一次,进步一点。
原文链接:https://juejin.cn/post/7340077302432595987 作者:人猫神话