Web 功能:
@function
维护大型样式表通常会导致逻辑重复,尤其是在处理渐变或响应式布局模式等设计体系令牌时。
借助 CSS @function at 规则,您可以将此逻辑封装到可重用的参数化函数中,从而使 CSS 更易于维护、更一致且更 DRY(不重复)。
@function 语法
自定义函数使用 @function 规则进行定义,后跟一个带短划线的名称和一个参数列表。该函数会使用 result 属性返回值。
@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
/* Logic goes here */
result: var(--input1);
}
关键概念
- 参数:必须以双短划线 (
--) 开头。 - 默认值:您可以使用英文冒号 (
:) 提供默认值。 - 结果:
result属性决定了函数返回的值。函数正文中最后声明的result胜出。 - 作用域:在函数内部定义的形参和变量具有局部作用域。
- 类型:您可以使用括号表示法(例如
<color>)要求参数和返回值与 CSS 类型匹配,并使用type函数(例如type(<number> | <percentage>))允许使用多种类型。
实际示例
1. 设计体系令牌(渐变)
通过封装渐变逻辑,确保整个应用中的颜色渐变效果保持一致。--angle 提供了一个默认值,以提供可被覆盖的一致性。
@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}
.card {
background: --fancy-gradient(#ed73d7, #5d87e9);
}
2. 条件布局逻辑
您可以直接在函数中使用 @media 或其他查询,以便根据环境返回不同的值。在函数中使用条件逻辑时,请注意,@function 不会在 result 的第一个值处“返回”,而是遵循 CSS 级联,并解析为根据屏幕尺寸、容器尺寸或其他查询匹配的最后一个值。
@function --grid-template(--count <number>){
/* MANDATORY: Put default value first. */
result: 1fr; /* Default: stack */
@media (min-width: 800px) {
result: repeat(var(--count), 1fr); /* Grid on larger screens */
}
}
main {
display: grid;
grid-template-columns: --grid-template(2);
}
最佳做法
- 使用带短划线的名称:始终在函数名称和参数名称前加上
--。 - 提供默认值:通过提供合理的默认值,使函数更加稳健。
- 力求简单:仅对实际重复或复杂的逻辑使用函数。不要过度设计简单的属性值对。
- 使用类型:确保参数和返回值符合预期类型。
- 考虑使用预编译的替代方案:对于不依赖于用户输入、媒体查询或其他客户端变体的函数,请考虑使用 CSS 预编译器,以避免在客户端上执行不必要的工作。
后备策略
在不支持 CSS 函数的浏览器中,使用 CSS 函数设置的值将无效。如需支持其他浏览器,请先为该属性提供后备值。在支持 CSS 函数的浏览器中,此设置将被覆盖。
.card {
/* Provide fallback, in this case a solid color. */
background: #5d87e9;
background: --fancy-gradient(#ed73d7, #5d87e9);
}
main {
/* Provide fallback, in this case a simple stacked default. */
grid-template-columns: 1fr;
grid-template-columns: --grid-template(2);
}
如果需要减少样式重复,同时支持其他浏览器,请考虑使用具有函数的 CSS 预编译器,例如 Sass。