在css里优雅地使用if函数

59 阅读4分钟

1. 基本信息

从 Chrome 137 开始,可以使用 if() 函数试用 CSS 内嵌条件语句。以前要根据条件实现不同css类名的切换,往往需要额外引入媒体查询、js代码介入等诸多复杂的逻辑。但是css if函数的出现,使得开发者可以更加优雅的处理某些复杂需求。

CSS if() 函数的运作方式是使用一系列条件-值对,其结构如下所示:

property: if(condition-1: value-1; condition-2: value-2; condition-3: value-3);

使用else

property: if(condition-1: value-1; condition-2: value-2; condition-3: value-3; else: value-4);

if()函数主要在三类查询中发挥作用,可以应对常见的样式决策需求:

  • 内联媒体查询:使用 media()直接响应视口变化,如根据屏幕方向或尺寸调整布局、字体大小等。
  • 内联支持查询:使用 supports()优雅地处理浏览器兼容性,为不支持新特性的浏览器提供降级方案。
  • 基于状态的样式:使用 style()配合 CSS 变量,根据元素自身状态(如主题、类型)动态切换样式,非常适合组件开发。

2. 内联媒体查询

使用 if() 是将内嵌媒体查询添加到样式的绝佳方式。

2.1 case

检查用户的主题设置(浅色或深色),或针对视口宽度执行内嵌媒体查询。以下示例展示了指针设备的媒体查询。对于具有精细指针(例如鼠标)的设备,按钮的默认大小为 30 像素;但对于具有粗略指针的触摸屏设备,按钮的大小应至少为 44 像素,以便提供适当的触摸间距,从而更易于访问。(简单的来说在pc里面按钮设置成30像素,在移动端设置成44px)

button {
  aspect-ratio: 1;
  width: if(media(any-pointer: fine): 30px; else: 44px);
}

上面代码等同于

button {
  aspect-ratio: 1;
  width: 44px;
}

@media (any-pointer: fine) {
  button {
    width: 30px;
  }
}

关于any-pointer

any-pointer:

none
没有可用的定点设备。

coarse
至少有一个输入途径包含一个精度有限的定点装置。

fine
至少有一个输入途径包含一个精确的定点装置。

具体效果如下

移动端:

pc:

在线地址:codepen.io/web-dot-dev…

3. 内联支持查询

优雅地处理浏览器兼容性,为不支持新特性的浏览器提供降级方案。

3.1 case

需检查是否支持 OKLCH 等广色域色彩

body {
  background-color: if(
    supports(color: oklch(0.7 0.185 232)): oklch(0.7 0.185 232) ; else: #00adf3;
  );

  &::after {
    content: if(
      supports(color: oklch(0.7 0.185 232)): "Your browser supports OKLCH" ;
        else: "Your browser does not suport OKLCH" ;
    );
  }
}

等同于

/* 基础样式 (降级方案) */
body {
  background-color: #00adf3;
}

body::after {
  content: "Your browser does not support OKLCH";
}

@supports (color: oklch(0.7 0.185 232)) {
  body {
    background-color: oklch(0.7 0.185 232);
  }

  body::after {
    content: "Your browser supports OKLCH";
  }
}

如果浏览器支持 oklch 色彩空间,用户会看到更鲜艳的颜色,并且还会在 ::after 伪内容中收到消息:“您的浏览器支持 OKLCH”。

效果:

在线地址:codesandbox.io/p/sandbox/3…

4. 可视化界面状态

使用 style()配合 CSS 变量,根据元素自身状态(如主题、类型)动态切换样式。

4.1 case

根据进度条的界面状态(待处理或已完成)设置其样式。直接将状态存储在数据属性或自定义属性中,然后使用 if() 对该属性内嵌应用样式。根据data-status设置背景颜色以及网格布局所在列数。

    <div class="container">
      <div class="card" data-status="pending">
        <div class="title">构建演示以展示 CSS 中的 <code>if()</code> 函数</div>
        <figure class="user">
          <figcaption>pending</figcaption>
        </figure>
      </div>

      <div class="card" data-status="complete">
        <div class="title">在此演示中创建一个带有数据状态的 div</div>
        <figure class="user">
          <figcaption>complete</figcaption>
        </figure>
      </div>

      <div class="card" data-status="pending">
        <div class="title">使此演示更具功能性和情境性</div>
        <figure class="user">
          <figcaption>pending</figcaption>
        </figure>
      </div>

      <div class="card" data-status="complete">
        <div class="title">看看演示</div>
        <figure class="user">
          <figcaption>complete</figcaption>
        </figure>
      </div>

      <div class="card" data-status="inactive">
        <div class="title">击掌</div>
        <figure class="user">
          <figcaption>inactive</figcaption>
        </figure>
      </div>

      <div class="card" data-status="complete">
        <div class="title">哈哈啊哈</div>
        <figure class="user">
          <figcaption>complete</figcaption>
        </figure>
      </div>
    </div>
.card {
  --status: attr(data-status type(<custom-ident>));
  border: 1px solid;
  border-color: if(
    style(--status: pending): royalblue; style(--status: complete): seagreen;
      else: gray
  );
  background-color: if(
    style(--status: pending): #eff7fa; style(--status: complete): #f6fff6; else:
      #f7f7f7
  );
  grid-column: if(
    style(--status: pending): 1; style(--status: complete): 2; else: 3
  );
}

效果:

在线地址:codesandbox.io/p/sandbox/v…

5. 后述

新特性,目前兼容性比较差,Chrome 137+浏览器支持。

参考:developer.chrome.com/blog/if-art…

关注我,带你了解前沿前端知识

fechan_副本.jpg