先记住这个答案
@supports 检查浏览器是否接受某条 CSS 声明,例如 @supports (display: grid);@media 检查视口宽度、指针类型、用户偏好等当前环境。两者回答的是不同问题。渐进增强先写不用新特性也能阅读的基础布局,再在 @supports 中加入新布局;若还需足够宽的屏幕,可再嵌套 @media。
@supports检测声明支持@media检测环境条件- 基础样式应独立可用
- 两种条件可以嵌套
先有回退,再有增强
一个列表在旧环境至少应顺序展示内容。支持 Grid 且屏幕够宽时,才改成三列。这样两个条件之一不满足,读者仍能看到完整内容。
.list { display: block; }
@supports (display: grid) {
@media (min-width: 48rem) {
.list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
}
}外层判断 CSS 能力,内层判断当前视口;两者都成立才进入三列。窄屏即便支持 Grid,仍按基础布局展示。反过来,宽屏但不支持 Grid,也保留基础布局。 特性检测只是语法能力判断。浏览器支持某声明,不代表字体、内容长度和列宽就一定满足设计要求,还要实际检查布局。
不要用错检测工具
深色模式是用户环境偏好,可用 @media (prefers-color-scheme: dark);某属性值是否被接受可用 @supports (property: value)。要根据组件所在容器宽度切换,则是 @container 的职责。
三种查询可以组合,但每增加一层限制都要说明真实需求。若没有兼容旧浏览器的需要,额外包一层 @supports 只会增加维护成本。
@supports 接受声明,只说明解析器认识这组属性和值,不会替你判断组合布局是否合理。示例中旧环境保留块级列表,可以阅读;新环境里即使 Grid 可用,也要看三列在 48rem 附近是否容得下最长的标题。若标题挤坏了卡片,应调列宽或断点,而不是继续增加一个“支持 Grid”条件。能力检测和布局验收是两步。
容易答错的地方
- 用
@media判断浏览器是否支持 Grid - 视口宽度和 CSS 特性支持没有必然关系。大屏旧浏览器也可能不认识 Grid。
- 认为
@supports命中就保证视觉正确 - 它不检查内容溢出、字体加载或用户缩放。增强后的实际排版仍需验收。
面试官还会怎么问?
如何检测多个特性都支持?
在 @supports 条件中用 and 组合声明测试,只有全部满足才应用规则。
想在不支持某特性时应用样式怎么写?
可以用 not 条件,但通常先写普通回退,再写支持时的增强规则更容易维护。
@supports 能测试图片是否可解码吗?
它主要测试 CSS 声明支持,不适合决定内容图片格式;内容图可用 <picture> 和 type。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。