CSS 播客 - 第 020 集:函数
在本课程的学习过程中,您已经接触了一些 CSS 函数。在 grid 模块中,您已了解 minmax()
和 fit-content()
,它们可帮助您调整元素大小。在 color 模块中,您已了解 rgb()
和 hsl()
,它们可帮助您定义颜色。
与许多其他编程语言一样,CSS 具有许多内置函数,您可以随时使用这些函数。
每个 CSS 函数都有特定用途,在本课程中,您将大致了解这些函数,从而更好地了解在何处以及如何使用它们。
什么是函数?
函数是用于完成特定任务的有名称且独立的代码段。为函数命名是为了便于您在代码中调用该函数,以及向该函数传递数据。这称为传递参数。
许多 CSS 函数都是纯函数,这意味着,如果您向这些函数传递相同的参数,它们将始终返回相同的结果,无论代码的其余部分发生了什么。这些函数通常会在 CSS 中的值发生变化时重新计算,与该语言中的其他元素(例如 currentColor
等计算的级联值)类似。
在 CSS 中,您只能使用提供的函数,而不能编写自己的函数,但在某些上下文中,函数可以嵌套在彼此内,从而提高灵活性。我们将在本单元的后面部分详细介绍这一点。
功能选择器
.post :is(h1, h2, h3) {
line-height: 1.2;
}
您在伪类模块中了解了函数选择器,其中详细介绍了 :is()
和 :not()
等函数。传递给这些函数的参数是 CSS 选择器,系统会对这些选择器进行求值。如果存在与元素匹配的条件,系统会将 CSS 规则的其余部分应用于这些元素。
自定义属性和 var()
:root {
--base-color: #ff00ff;
}
.my-element {
background: var(--base-color);
}
自定义属性是一种变量,可让您对 CSS 代码中的值进行分词。自定义属性也会受到级联的影响,这意味着它们可以根据上下文进行操作或重新定义。自定义属性必须带有两个短划线 (--
) 前缀,并且区分大小写。
var()
函数接受一个必需参数:您尝试作为值返回的自定义属性。
在前面的代码段中,var()
函数将 --base-color
作为实参传递。如果定义了 --base-color
,则 var()
将返回该值。
.my-element {
background: var(--base-color, hotpink);
}
您还可以将回退声明值传递给 var()
函数。这意味着,如果找不到 --base-color
,系统会改用传递的声明,在本示例中,就是 hotpink
颜色。
会返回值的函数
var()
函数只是返回值的 CSS 函数之一。attr()
和 url()
等函数的结构与 var()
类似:您可以传递一个或多个参数,并在 CSS 声明的右侧使用这些参数。
a::after {
content: attr(href);
}
此处的 attr()
函数会获取 <a>
元素的 href
属性的内容,并将其设置为 ::after
伪元素的 content
。如果 <a>
元素的 href
属性的值发生变化,则此变化会自动反映在此 content
属性中。
.my-element {
background-image: url('/path/to/image.jpg');
}
url()
函数接受字符串网址,用于加载图片、字体和内容。如果未传入有效网址,或者找不到网址指向的资源,url()
函数将不会返回任何内容。
颜色函数
您已在 color 模块中全面了解了颜色函数。 如果您尚未阅读该文章,我们强烈建议您阅读。
CSS 中的一些可用颜色函数包括 rgb()
、hsl()
、lab()
、lch()
、oklab()
、oklch()
和 color()
。所有这些方法的形式都类似,即传入配置参数并返回颜色。
数学表达式
与许多其他编程语言一样,CSS 提供了实用的数学函数来协助执行各种类型的计算。
算术函数
calc()
calc()
函数接受单个数学表达式作为参数。此数学表达式可以是混合类型,例如长度、数字、角度和频率。您也可以混合使用这些单位。
.my-element {
width: calc(100% - 2rem);
}
在此示例中,calc()
函数用于将元素的宽度设为其包含父元素的 100%,然后从该计算值中移除 2rem
。
:root {
--root-height: 5rem;
}
.my-element {
width: calc(calc(10% + 2rem) * 2);
height: calc(var(--root-height) * 3);
}
calc()
函数可以嵌套在另一个 calc()
函数中。您还可以将自定义属性作为表达式的一部分传递给 var()
函数。
min()
和max()
min()
函数会返回传递的一个或多个参数中最小的计算值。max()
函数的用法与之相反:获取传递的 1 个或多个参数中的最大值。
.my-element {
width: min(20vw, 30rem);
height: max(20vh, 20rem);
}
在此示例中,宽度应为 20vw
(即 视口宽度的 20%)和 30rem
之间的最小值。高度应为 20vh
(即 视口高度的 20%)和 20rem
之间的最大值。
clamp()
clamp()
函数接受三个参数:最小尺寸、理想尺寸和最大尺寸。
h1 {
font-size: clamp(2rem, 1rem + 3vw, 3rem);
}
在此示例中,font-size
将根据视口的宽度进行流式布局。vw
单元会添加到 rem
单元中,以协助屏幕缩放,因为无论缩放级别如何,vw
单元的大小都将保持不变。通过乘以 rem
单位(基于根字体大小),为 clamp()
函数提供了一个相对的计算点。
如需详细了解 min()
、max()
和 clamp
() 函数,请参阅介绍这些函数的文章。
三角函数
借助三角函数,您可以根据角度查找圆上的任意点、对声波等周期性现象进行建模、描述轨道等。在 CSS 中,您可以使用三角函数根据旋转、时间动画、根据某个点旋转元素等用途来设置属性。
如需了解详情和示例,请参阅我们的关于三角函数的文章。
sin()
、cos()
和tan()
sin()
、cos()
和 tan()
函数接受一个角度参数,并分别返回正弦、余弦和正切。sin()
和 cos()
函数会返回一个介于 -1
和 1
之间的数字。tan()
函数会返回一个介于 -Infinity
和 +Infinity
之间的数字。角度参数可以是任何受支持的角度单位。
:root {
--sine-degrees: sin(45deg); /* returns 0.7071 */
--sine-radians: sin(0.7853rad); /* returns 0.7071 */
}
在前面的示例中,--sine-degrees
和 --sine-radians
具有相同的值(在本例中为 0.7071
)。
在前面的示例中,sin()
和 cos()
函数用于通过将结果乘以指定的半径,在 x
和 y
轴上创建振荡动画。同时使用这两个函数可实现绕转动画。
我们使用自定义属性 --angle
来为所有函数调用的角度进行流畅的动画效果。
asin()
、acos()
和atan()
asin()
、acos()
和 atan()
是 sin()
、cos()
和 tan()
函数的反函数,它们接受一个数字作为参数,并返回介于 -90deg
和 90deg
之间的角度值。asin()
和 acos()
函数接受介于 -1
和 1
之间的数字,而 atan()
函数接受介于 -Infinity
和 +Infinity
之间的数字。
:root {
--degrees: asin(0.7071); /* returns 45deg */
}
atan2()
atan2()
函数接受两个参数,表示相对于原点的点,并返回表示该点方向的角度。您可以使用此属性将元素旋转到朝向特定点的位置。参数可以是数字、尺寸单位或百分比,但两个参数必须是同一类型。
在上面的示例中,atan2()
函数用于确定视口中心与当前鼠标位置之间的角度。请注意,y
值是第一个参数,x
值是第二个参数。然后,系统会使用该角度来相对于“眼睛”中心定位“瞳孔”,以便它们跟随鼠标。
hypot()
hypot()
函数接受两个长度参数,表示一个直角三角形的边,并返回斜边的长度。您可以将其用作使用指数函数计算此值的快捷方式。这两个参数必须采用相同的单位类型,并且 hypot()
将返回相同的类型。
:root {
--use-ems: hypot(3em, 4em); /* returns 5em */
--use-px: hypot(30px, 40px); /* returns 50px */
}
指数函数
pow()
和exp()
pow()
函数接受两个数字参数(底数和指数),并将底数乘以指数的幂。这两个参数都必须是没有单位的数字。exp()
函数接受一个参数,等同于使用 e 作为底数调用 pow()
函数。
.my-element {
width: calc(10px * pow(4, 2); /* 10px * (4 * 4) == 160px */
}
sqrt()
sqrt()
函数采用数字参数,并返回其平方根。参数不得包含单位。
:root {
--root: sqrt(25); /* returns 5 */
}
log()
log()
函数会返回数值的对数。如果传递一个参数,则会返回自然对数。如果传递第二个参数,log()
函数将使用第二个参数作为对数的底数。
:root {
--log2: log(16, 2); /* returns 4 */
--logn: log(16); /* returns 2.7725 */
}
与签名相关的函数
abs()
abs()
函数接受一个数字参数,并返回该参数值的绝对(正)值。
.my-element {
color: rgba(0, 0, 0, abs(-1));
}
在前面的示例中,alpha
值为 -1
会导致文本透明,但 abs()
函数会返回 1
的绝对值,这会导致文本完全不透明。
sign()
sign()
函数接受一个数字参数,并返回该参数的符号。正值会返回 1
,负值会返回 -1
。零值会返回 0
。
.my-element {
top: calc(50vh + 25vh * sign(var(--value));
}
在前面的示例中,如果 --value
为正值,则顶部值将为 75vh
。如果为负值,则上限值为 25vh
。如果为零,则顶部值将为 50vh
。
形状
clip-path
、offset-path
和 shape-outside
CSS 属性使用形状来视觉剪裁框,或提供形状以便内容流动。
有些形状函数可与这两个属性搭配使用。简单形状(例如 circle()
、ellipse()
和 inset()
)采用配置参数来调整大小。更复杂的形状(例如 polygon()
)采用以英文逗号分隔的 X 轴和 Y 轴值对来创建自定义形状。
.circle {
clip-path: circle(50%);
}
.polygon {
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
}
与 polygon()
一样,还有一个 path()
函数,它将 SVG 填充规则作为参数。这样,您就可以在 Illustrator 或 Inkscape 等图形工具中绘制高度复杂的形状,然后将其复制到 CSS 中。
转换
在 CSS 函数概览的最后,我们介绍了 transform 函数,它可以使元素倾斜、调整大小,甚至更改元素的深度。以下所有函数都与 transform
属性搭配使用。
旋转
您可以使用 rotate()
函数旋转元素,该函数会沿元素的中心轴旋转元素。您还可以改用 rotateX()
、rotateY()
和 rotateZ()
函数沿特定轴旋转元素。您可以传递度数、转数和弧度单位来确定旋转角度。
.my-element {
transform: rotateX(10deg) rotateY(10deg) rotateZ(10deg);
}
rotate3d()
函数接受四个参数。
前 3 个参数是数字,用于定义 X、Y 和 Z 坐标。 第四个参数是旋转,与其他旋转函数一样,接受度数、角度和圈数。
.my-element {
transform: rotate3d(1, 1, 1, 10deg);
}
缩放
您可以使用 transform
和 scale()
函数更改元素的缩放比例。该函数接受一个或两个数字作为值,用于确定正向或负向缩放。如果您仅定义一个数值参数,X 轴和 Y 轴将采用相同的缩放比例,同时定义这两个参数是 X 和 Y 的简写形式。与 rotate()
一样,您可以使用 scaleX()
、scaleY()
和 scaleZ()
函数,以沿特定轴缩放元素。
.my-element {
transform: scaleX(1.2) scaleY(1.2);
}
与 rotate
函数一样,还有一个 scale3d()
函数。这与 scale()
类似,但它接受三个参数:X、Y 和 Z 缩放比例。
翻译
translate()
函数会移动元素,同时保持其在文档流中的原有位置。它们接受长度和百分比值作为参数。如果定义了一个实参,translate()
函数会沿 X 轴平移元素;如果定义了两个实参,translate()
函数会沿 X 轴和 Y 轴平移元素。
.my-element {
transform: translatex(40px) translatey(25px);
}
与其他转换函数一样,您可以使用 translateX
、translateY
和 translateZ
针对特定轴使用特定函数。您还可以使用 translate3d
,它允许您在一个函数中定义 X、Y 和 Z 平移。
偏差
您可以使用接受角度作为参数的 skew()
函数来使元素倾斜。skew()
函数的运作方式与 translate()
非常相似。如果您仅定义一个参数,则只会影响 X 轴;如果您同时定义这两个参数,则会影响 X 轴和 Y 轴。您还可以使用 skewX
和 skewY
分别影响每个轴。
.my-element {
transform: skew(10deg);
}
车头朝上
最后,您可以使用 perspective
属性(属于转换属性系列)来更改用户与 Z 平面之间的距离。这会营造距离感,可用于在设计中营造景深。
David Desandro 在其非常实用的文章中提供了以下示例,展示了如何将该属性与 perspective-origin-x
和 perspective-origin-y
属性搭配使用,以打造真正的 3D 体验。
动画函数、渐变和滤镜
CSS 还提供了一些函数,可帮助您为元素添加动画效果、为元素应用渐变,以及使用图形滤镜来操控元素的外观。为使本单元尽可能简洁,相关内容在链接的模块中进行了介绍。它们的结构与本模块中演示的函数类似。
检查您的理解情况
测试您对函数的了解
CSS 函数可以通过哪些字符进行识别?
[]
{}
()
::
:
CSS 是否有内置数学函数?
calc()
函数可以放置在其他 calc()
中,例如 font-size: calc(10px + calc(5px * 3));
以下哪些是 sin()
和 cos()
的有效实参?
45
10deg
5em
pi
以下哪些是 CSS 形状函数?
ellipse()
square()
circle()
rect()
inset()
polygon()