如何在 CSS 中正确使用 if()

0 阅读5分钟

CSS 正在不断进化,而 if() 函数 的引入,就是其中一个非常值得关注的新特性。它让我们可以直接在 CSS 中编写条件逻辑,根据不同状态动态切换样式,从而减少对 JavaScript 的依赖。

if() 的语法非常直观,甚至有点类似我们熟悉的编程语言中的条件判断。但在实际使用中,它的行为却和直觉并不完全一致。如果不了解其中的细节,很容易写出“看起来正确,但结果却错误”的代码。

其中最常见的一个问题是:if() 的判断依据到底是“计算后的值”,还是“原始值”

这个问题看似简单,却直接决定了你的条件是否能够正确命中,也是很多人第一次使用 if() 时踩坑的根源。接下来,我们通过一个具体的例子来看看这个问题是如何产生的,以及应该如何正确处理。

来看一个简单的例子:

.box {
    --n: 6;
    --f: calc(var(--n) / 2);
    background: if(
        style(--f: 3): red;
        else: green
    );
}

从直觉上看,--n6--f 计算后应该是 3 ,因此条件成立,.box 元素的背景颜色理应是红色(red)。但实际渲染结果却是绿色(green)。

问题的关键在于 if() 中的 style() 并不会基于“计算后的结果”进行判断,而是直接对“原始值”进行字符串匹配。也就是说,浏览器看到的是 calc(var(--n) / 2) 这个表达式本身,而不是它计算后的数值 3 ,因此条件匹配失败。

.box {
    --n: 6;
    --f: calc(var(--n) / 2);
    /* 不匹配,返回 false,因此背景颜色是 green*/
    background: if(
        style(--f: 3): red;
        else: green
    );
}

.box {
    --n: 6;
    --f: calc(var(--n) / 2);
    /* 匹配,返回 true,因此背景颜色是 red */
    background: if(
        style(--f: calc(var(--n) / 2)): red;
        else: green
    );
}

Demo 地址:codepen.io/airen/full/…

正确方式:使用 @property 让值参与计算

如果希望 if() 的判断基于“计算后的结果”,而不是原始字符串,就需要借助 @property 来注册自定义属性。通过这种方式,可以明确告诉浏览器该变量的类型,从而让它在参与比较之前先完成计算与解析。例如:

@property --f {
    syntax: "<number>";
    inherits: false;
    initial-value: 0;
}

.box {
    --n: 6;
    --f: calc(var(--n) / 2);
    background: if(style(--f: 3): red; else: green);
}

在这个例子中,--f 被注册为 <number> 类型,因此浏览器会先对 calc(var(--n)/2) 进行求值,得到数值 3,再参与条件判断。也正因为如此,if() 中的条件能够正确匹配,最终背景颜色会按预期显示为红色。

Demo 地址:codepen.io/airen/full/…

换句话说,一旦自定义属性具备了明确的类型信息,它就不再只是一个“字符串”,而是一个可以参与计算和比较的真正数值。这正是解决该问题的关键所在。

温馨提示:如果你想更深入了解 @property 的用法与原理,推荐继续阅读《CSS 自定义属性: @property》和《Web UI:你需要的是 @property》,可以帮助你更系统地掌握这一特性。

不涉及计算时:无需注册属性

当自定义属性的值只是一个固定值,而不包含 calc() 等计算表达式时,其实不需要使用 @property 进行注册。这种情况下,if() 的判断逻辑非常直接——它只是对值进行字符串层面的精确匹配。例如:

.box {
    --f: error;
    background: if(style(--f: error): red; else: green);
}

.box {
    --v: 0;
    background: if(style(--v: 0): red; else: green);
}

在这个例子中,--f--v 都是明确的静态值,浏览器无需进行额外计算,因此 if() 可以直接完成匹配,并按预期应用对应的样式。

Demo 地址:codepen.io/airen/full/…

也就是说,只要不涉及计算,if() 的行为就是简单可靠的字符串比较,这也是它最直观、最容易理解的一种使用方式。

另一种技巧:使用 = 进行数值比较

除了使用 @property 让属性参与计算之外,还有一种更简洁的方式可以达到相同效果,那就是在 if() 中使用 = 运算符进行匹配。例如:

.box {
    --n: 6;
    --f: calc(var(--n)/2);
    background: if(style(--f = 3): red; else: green);
}

这种写法与使用 : 的行为本质不同。= 会基于“计算后的结果”进行比较,而不是简单的字符串匹配。因此,即使 --f 是通过 calc() 计算得来的,也能正确参与判断。

也正因为如此,这种方式可以在不注册 @property 的情况下,依然得到正确的结果。在很多场景下,它是一种更轻量、更实用的解决方案。

如果你继续深入探索,会发现 if() 还可以与样式查询(style queries)结合,构建更强大的条件判断能力,例如基于范围的比较(>< 等)。这类用法已经超出了基础范畴,属于更进阶的技巧。如果你想进一步了解相关内容,可以查阅《CSS 技巧:样式查询与 if() 函数隐藏技巧》,会有更系统和深入的讲解。

小结

从整体来看,if() 的判断方式可以归纳为两种核心逻辑:一种是使用 : 进行匹配,此时本质上是字符串级别的比较,不会触发计算;另一种是使用 =>< 等,则会基于计算后的结果进行数值比较。

理解这一区别至关重要。它不仅关系到条件是否能够正确命中,也直接决定了你是否需要借助 @property 来让自定义属性参与计算,从而影响最终的渲染结果。

掌握这一点,你就能更从容地在实际项目中使用 if(),避免那些“看起来没问题,但结果却不对”的常见陷阱。