如何在SCSS中针对CSS自定义属性编写if-else条件判断?
嘿,你遇到的这个坑其实挺常见的——核心问题是SCSS的@if是编译时干活的,而CSS自定义属性(就是你用的--color-in这类变量)是浏览器运行时才生效的。你之前直接在@if里写var(--color-in),编译的时候它就是个纯字符串"var(--color-in)",根本不知道运行时这个变量实际是啥值,所以你的条件判断自然不会按预期工作。
下面给你两种靠谱的解决方案,按需选就行:
方案1:纯CSS实现(首推,贴合CSS变量的特性)
不用纠结SCSS的@if,直接用CSS变量的fallback机制和样式层叠来实现。思路很简单:先给元素设默认的background-color: currentColor,然后当两个变量有有效值时,用渐变背景覆盖它:
.your-element { // 默认兜底:变量无效时显示这个 background-color: currentColor; // 变量有效时,渐变背景会覆盖上面的默认样式 background: linear-gradient(to left, transparent, rgba(255,255,255,.5)), linear-gradient(to left, var(--color-in, transparent), var(--color-out, transparent)); }
这里的var(--color-in, transparent)是关键:如果--color-in是你一开始设的none或者没定义,就会用transparent当备选值。当两个渐变的颜色都是透明时,整个渐变背景相当于无效,浏览器就会自动回退到之前设置的background-color,完美实现你要的if-else效果。
方案2:把JS的值同步给SCSS(编译时+运行时结合)
如果你非得用SCSS的@if逻辑,那得把JavaScript设置的颜色值同步成SCSS能识别的变量才行,步骤如下:
- 先通过JS给页面注入一个内联样式,定义SCSS能读取的变量:
// 假设你已经拿到了要设置的colorIn和colorOut值 const styleSheet = document.createElement('style'); styleSheet.textContent = ` :root { --scss-color-in: ${colorIn || 'none'}; --scss-color-out: ${colorOut || 'none'}; } `; document.head.appendChild(styleSheet);
- 然后在SCSS里把这些CSS变量转成SCSS变量,再用
@if判断:
// 把CSS变量转成SCSS变量 $color-in: var(--scss-color-in); $color-out: var(--scss-color-out); .your-element { @if $color-in != 'none' and $color-out != 'none' { background: linear-gradient(to left, transparent, rgba(255,255,255,.5)), linear-gradient(to left, $color-in, $color-out); } @else { background-color: currentColor; } }
注意哦,这种方式要确保JS在页面加载时及时注入样式,不然可能会有短暂的样式闪烁问题。
再给你掰扯清楚:SCSS是预处理器,@if在你编译代码的时候就执行完了,这时候var(--color-in)就是个普通字符串,不是浏览器运行时解析出来的实际颜色。你写的@if var(--color-in) && var(--color-out),相当于判断两个非空字符串是不是真的——那肯定是真的啊!所以不管你的变量实际有没有值,都会执行@if里的代码,这就是为啥逻辑失效了。
内容的提问来源于stack exchange,提问作者SK121212

