CSS if()条件语句和条件逻辑入门

38 阅读8分钟

原文:markodenic.com/introductio…

CSS if()语句

条件逻辑是任何编写过程序的人都熟悉的概念。像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特性查询,仅当浏览器支持特定的属性值对时才应用样式。你可以使用andornot运算符组合多个条件。
  • 容器查询@container)根据父容器的大小或样式应用样式。
  • CSS自定义属性和伪类(hoverfocusnth-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没有设置为brightdull,所以它将被设置为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条件,并为响应式设计的未来做好准备。