深色模式
CSS if() 函数在 State of CSS 2023 调查中以"最期待的新特性"高票通过后,2025 年终于迎来了浏览器实验性实现。它将允许在 CSS 属性值中内联书写条件逻辑,彻底改变目前必须靠 CSS 变量 + 媒体查询 + 选择器拼凑的条件样式写法。
注意:截至 2025 年 1 月,
if()仍处于 CSS Working Group 规范草案阶段,Chrome 实验性标志后可用,尚未稳定。
当前痛点:条件样式的变通方案
css
/* 现在要根据变量写条件样式,只能用选择器变通 */
:root {
--is-dark: 0; /* 0 或 1 */
}
/* 利用 calc() hack(只适用于数值) */
.bg {
/* (1 - var(--is-dark)) × 255 + var(--is-dark) × 0 */
/* 0 → 255(白色),1 → 0(黑色)*/
background: rgb(
calc((1 - var(--is-dark)) * 255),
calc((1 - var(--is-dark)) * 255),
calc((1 - var(--is-dark)) * 255)
);
}
/* 或者靠 CSS 选择器 :has()/:is() */
:root:has([data-theme="dark"]) .bg {
background: black;
}
:root:not(:has([data-theme="dark"])) .bg {
background: white;
}CSS if() 语法(规范草案)
css
/* 基本语法 */
.element {
color: if(style(--variant: primary): blue; else: gray);
}
/* 多条件 */
.button {
background: if(
style(--size: large): hsl(200 80% 40%) ;
style(--size: small): hsl(200 80% 60%) ; else: hsl(200 80% 50%)
);
padding: if(
style(--size: large): 12px 24px; style(--size: small): 4px 8px; else: 8px
16px
);
}
/* 使用 media 条件 */
.layout {
display: if(media(width >= 768px): grid; else: flex);
grid-template-columns: if(
media(width >= 1024px): repeat(3, 1fr) ;
media(width >= 768px): repeat(2, 1fr) ; else: 1fr
);
}
/* 使用 supports 条件 */
.animation {
animation-timeline: if(
supports(animation-timeline: scroll()): scroll() ; else: none
);
}if() 与自定义属性组合:组件变体系统
这是 if() 最强大的应用场景——无需修改 HTML 结构,纯靠 CSS 变量驱动组件变体:
css
/* 定义一个支持 variant 和 size 变体的按钮 */
.button {
--variant: primary; /* 默认值 */
--size: md;
/* 使用 if() 根据变量决定所有相关属性 */
background: if(
style(--variant: primary): var(--color-primary) ;
style(--variant: secondary): transparent;
style(--variant: danger): var(--color-danger) ; else: var(--color-primary)
);
color: if(style(--variant: secondary): var(--color-primary) ; else: white);
border: if(
style(--variant: secondary): 1px solid var(--color-primary) ; else: none
);
padding: if(
style(--size: sm): 4px 10px; style(--size: lg): 12px 28px; else: 8px 16px
);
font-size: if(style(--size: sm): 13px; style(--size: lg): 17px; else: 15px);
}html
<!-- 仅通过 CSS 变量切换变体 -->
<button class="button" style="--variant: primary; --size: lg">
大号主按钮
</button>
<button class="button" style="--variant: secondary">次要按钮</button>
<button class="button" style="--variant: danger; --size: sm">
小号危险按钮
</button>与现有方案的对比
方案对比(以"按钮变体"为例,3 种变体 × 3 种尺寸):
方案 代码量 动态切换 运行时 JS 选择器特异性
─────────────────────────────────────────────────────────────────
CSS 类名 (.btn-primary-lg) 多 靠 JS 需要 累加
CSS 变量 + 计算 hack 多 CSS 变量 无 无影响
CSS 选择器 :has() 组合 较多 CSS 变量 无 有影响
CSS if()(未来) 少 CSS 变量 无 无影响目前如何试用
bash
# Chrome 125+ 开启实验标志
# 地址栏输入:chrome://flags
# 搜索:CSS if()
# 或:--enable-experimental-web-platform-featurescss
/* 或通过 PostCSS 插件转换(polyfill 方案,部分兼容)*/
/* postcss-if-value 等插件正在开发中 */总结
CSS if() 代表了 CSS 条件逻辑的未来方向——将组件变体的逻辑内联到 CSS 中,减少对 JavaScript 的依赖,同时让 CSS 变量真正成为"主题/状态的单一来源"。虽然 2025 年初仍不适合生产使用,但值得现在就了解语法,等稳定化之后可以快速迁移。