在css里优雅地使用if函数
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:
在线地址:https://codepen.io/web-dot-dev/pen/xbGBEaY
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”。
效果:
在线地址:https://codesandbox.io/p/sandbox/323hhr
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);
}
效果:
在线地址:https://codesandbox.io/p/sandbox/vsdn7k
5. 后述
新特性,目前兼容性比较差,Chrome 137+浏览器支持。
参考:https://developer.chrome.com/blog/if-article?hl=zh-cn
关注我,带你了解前沿前端知识