条件逻辑是任何编写过程序的人都熟悉的概念。像JavaScript或Python这样的语言使用if/else语句来评估表达式,并根据条件是true还是false执行不同的代码块。直到最近,原生CSS还没有等价的运行时条件逻辑——开发者依靠媒体查询、特性查询或预处理器(如Sass/SCSS)来条件性地应用样式。
本指南将介绍:
- CSS中的新
if()函数 - 它与早期条件技术的区别
- 提供适合初学者的示例
- 常见问题解答
什么是"if语句",它与CSS有什么关系?
在编程中,if语句检查一个条件,然后当条件为true时运行一组指令,为false时运行另一组。你可以把它想象成电脑做决定——如果我在12点饿了,那我就去食堂。
在原生CSS的上下文中,在没有使用第三方解决方案(如Sass/SCSS)的情况下,条件逻辑是不可能实现的,Sass/SCSS已经提供了自己的@if指令多年。Sass在构建时编译这些指令;生成的CSS没有运行时条件逻辑。正如Sass文档所解释的,它提供了类似于JavaScript的流控制,允许仅当布尔表达式求值为true时才编译样式。
需要注意的是,CSS if语句在撰写本文时被认为是实验性的,浏览器支持仅限于Chrome、Edge、Opera、Android Browser和Chrome for Android。如果你在未来阅读本文,希望支持已经有所改善——你可以在Can I Use上查看当前状态。
没有if语句的条件样式
如果你不想使用Sass或SCSS,原生CSS用户确实可以通过其他方式"变通"缺乏if语句的问题,例如:
- 媒体查询(即
@media (min-width: 700px) { … })用于在特定屏幕尺寸下应用样式。这些是CSS条件规则模块的一部分,并且得到广泛支持。 - 使用
@supports的特性查询,仅当浏览器支持特定的属性值对时才应用样式。你可以使用and、or或not运算符组合多个条件。 - 容器查询(
@container)根据父容器的大小或样式应用样式。 - CSS自定义属性和伪类(
hover、focus、nth-child()等)用于基于状态的样式设计。
所有这些技术都允许你应用条件样式,但它们不是内联的if语句;它们需要单独的规则块。新的if()函数首次在属性值内部提供了内联条件逻辑。
介绍if()函数
if()的工作原理
CSS的if()函数是一个实验性的值函数,它允许你根据一系列条件选择一个值。MDN将其描述为提供"CSS属性值的条件逻辑",其工作方式类似于JavaScript的if…else语句。它可以在任何CSS属性的值内部使用。
一个if()函数包含一个或多个<if-condition> : <value>对,用分号分隔,可选地后跟else : <value>。条件按顺序评估;第一个评估为true的条件返回其关联的值。如果没有条件为真,则返回else值,或者函数返回一个保证无效的值。if与其开括号之间不能有空格;否则整个声明将无效。
CSS的if()函数允许你根据一系列条件设置CSS属性的值。这种条件逻辑的工作方式类似于JavaScript的if…else语句,可以在任何CSS属性的值内部使用。
语法概述
CSS的if()函数支持单个条件、多个条件和使用else条件的回退。让我们看一下下面的语法:
/* 单个条件 */
property: if(condition‑1 : value‑1;);
/* 多个条件 */
property: if(condition‑1 : value‑1;
condition‑2 : value‑2;
);
/* else条件 */
property: if(condition‑1 : value‑1;
else : fallback
);
/* 带else的多个条件 */
property: if(condition‑1 : value‑1;
condition‑2 : value‑2;
/* …根据需要添加更多条件 */
else : fallback
);
- 条件可以测试样式值、媒体查询或特性支持。
- 单个
else : value通常放在列表的末尾,作为回退/默认值。
if()中可用的查询类型
if()语句支持三种类型的查询,这意味着我们可以用三种类型的条件来做决定。下表分解了这三种查询类型:
| 查询类型 | 描述 |
|---|---|
style() | 测试同一元素上的计算样式或自定义属性。与容器样式查询不同,if()的style()查询不需要父元素。 |
media() | 检查媒体特性,类似于内联媒体查询。 |
supports() | 执行内联特性查询;如果浏览器支持指定的属性或函数,则返回该值。 |
在实践中使用if()
示例1 - 单个条件
在这个示例中,我创建了一个简单的单个条件if语句,当CSS自定义属性(CSS变量)p-color设置为bright时,段落文本颜色变为红色。
HTML
<p class="conditional-color">这是一个段落</p>
CSS
.conditional-color {
--p-color: bright;
color: if(style(--p-color: bright): red;);
}
示例2 - 多个条件和else
在这个示例中,我们扩展了示例1,添加了另一个条件和一个else。
HTML
<p class="multiple-conditions">这是一个段落</p>
CSS
.multiple-conditions {
--p-color: fancy;
color: if(
style(--p-color: bright): red;
style(--p-color: dull): gray;
else: orange;
);
}
从输出可以看出,因为p-color没有设置为bright或dull,所以它将被设置为orange。
示例3 - media()查询
在这个示例中,我们使用media()查询来检查视口是否宽于或窄于1000px,并根据此改变整个body的背景颜色。
body {
background-color: if(
media(width > 1000px): red;
media(width < 1000px): blue;
);
}
媒体查询已经是非常有用的条件CSS特性,常用于响应式设计。与if()结合,我们可以使用媒体查询来改变特定的属性值,而不是完整的选择器。
示例4 - supports()查询
在这个示例中,我们使用supports()来检查浏览器是否支持display: grid;,如果支持则使用它,否则使用display: block;。
如果你熟悉CSS,你可能会认为这在不使用if()的情况下已经是可能的(并且被广泛使用),你是对的。但让我们探索一下下面的差异……
不使用if(),你可以使用这个常见的实现:
/* 为不支持grid的浏览器提供回退 */
.container {
display: block;
}
/* 如果浏览器支持grid,则使用它 */
@supports (display: grid) {
.container {
display: grid;
}
}
但使用if(),我们可以用更少的行数实现相同的解决方案,如下所示:
.container {
display: if(
supports(display: grid): grid;
else: block;
);
}
常见问题解答
CSS支持真正的if/else语句吗?
原生CSS现在通过if()函数支持条件逻辑,该函数可以根据条件返回不同的值。然而,CSS不支持像Sass那样的@if块。if()只能存在于属性值内部,不能包装多个声明。同样重要的是要注意,在撰写本文时,if()的支持并不广泛,可能不适合生产网站。
if()函数是否被广泛支持?
不。在撰写本文时,MDN将if()标记为实验性,并警告开发者要仔细检查浏览器兼容性。查看Can I Use if()页面以获取最新的兼容性信息。
if()与@media或@supports有什么不同?
@media和@supports在条件为真时应用整个CSS块,而if()则内联返回单个属性值。当你需要对单个属性值进行细粒度控制(例如,调整单个宽度或颜色)时,使用if()。当你需要更改多个属性或应用复杂规则时,使用@media或@supports。
我可以将if()嵌套在其他函数中,或者将函数嵌套在if()中吗?
是的。if()可以嵌套在CSS函数中,反之亦然,只要结果值有效。例如:
margin-top: max(10px, if(media(width > 700px): 20px; else: 15px));
如果CSS有if(),我还需要Sass/SCSS吗?
Sass/SCSS对于变量、混合宏、循环和编译时逻辑仍然很有价值。if()函数在CSS中提供了运行时条件值,这是对Sass特性的补充,但不能替代它们。许多开发者将继续使用预处理器来组织和模块化样式表。if()也仍然没有在所有主流浏览器中得到完全支持,但Sass/SCSS是支持的——这种情况可能会随着时间的推移而改变,但可能需要数年时间才能达到广泛支持。
if()有哪些实际用例?
- 主题或模式切换——根据
-theme自定义属性选择颜色、字体或间距。 - 响应式调整——内联调整单个维度(例如,边距或宽度),而无需编写单独的
@media块。 - 特性回退——例如,尝试使用CSS grid,如果不支持则使用其他方法。
- 状态组件——根据
data-*属性或自定义属性(即状态、错误、成功)设置组件样式。
结论
新的if()函数是CSS工具箱中令人兴奋的新增功能。它带来了以前需要Sass或分散的媒体查询的内联条件逻辑。通过了解if()如何与style、media和support查询交互,并将其与自定义属性和数据属性结合使用,你可以编写更具表现力、更易维护的样式。请记住它的实验性状态,所以将本指南作为参考,今天就开始试验CSS条件,并为响应式设计的未来做好准备。