CSS 有了 if():条件样式不用再靠媒体查询叠罗汉

Chrome 137 起支持 CSS 的 if() 函数,可以在任意属性值里写条件分支,按自定义属性、媒体查询或特性支持来选择值。它不替代媒体查询,但能把大量重复的样式块收成一行。

过去想在 CSS 里表达“如果满足条件就用 A,否则用 B”,标准做法是把整块声明重复三遍:

.card { padding: 16px; }
@media (min-width: 60rem) { .card { padding: 24px; } }

Chrome 137 开始支持 if(),同样的事情可以写成一行:

.card {
  padding: if(media(min-width: 60rem): 24px; else: 16px);
}

它能判断什么

if() 的条件有三种:

  • style(--theme: dark):判断自定义属性的值;
  • media(...):判断媒体查询;
  • supports(...):判断浏览器是否支持某个特性。

按顺序求值,命中第一个为真的分支;都不命中就走 else。它出现在值的位置,所以任何属性都能用,包括 color、padding、grid-template-columns。

它解决的真实问题

站点做主题切换时,最常见的写法是给每个皮肤写一遍选择器:

[data-skin='riso'] .card { border-width: 3px; }
[data-skin='ink'] .card { border-width: 1px; }

用 if() 可以把“皮肤决定线宽”收进一个令牌:

:root {
  --card-border: if(
    style(--skin: riso): 3px;
    style(--skin: blueprint): 2px;
    else: 1px
  );
}

好处不是少敲几个字,而是让差异集中在一处:新增一套皮肤只改令牌,不用再补选择器。

和媒体查询、容器查询的分工

  • 需要“整块布局换形态”(比如侧栏从横向变纵向),仍然用 @media 或 @container,可读性更好;
  • 需要“某个值随条件变”,用 if() 更直接;
  • 需要“整站换主题”,自定义属性 + if() 的组合最省事。

兼容性怎么处理

在主流浏览器都支持之前,把它当渐进增强:先写一个兜底的普通声明,再用 if() 覆盖。不支持 if() 的浏览器会忽略整条声明,前面的兜底值继续生效——这正好是 CSS 一贯的容错方式。

.card { padding: 16px; padding: if(media(min-width: 60rem): 24px; else: 16px); }

一句判断

if() 不是“CSS 里的 JavaScript”,它只做一件事:在一个值的位置上做条件选择。但正因为值是最常变的东西,这一个能力就能把很多重复的样式块收掉。真正的收益出现在设计系统里——差异被压进令牌,而不是散落在选择器里。

封面图:CSS3 标识(Wikimedia Commons)。

← 返回文章列表

评论

…