@supports 谎言:当 CSS 说“是”,但浏览器说“LOL 不”。

发布: (2026年5月9日 GMT+8 23:02)
3 分钟阅读
原文: Dev.to

Source: Dev.to

Introduction

根据 CSS 规范,@supports at‑rule 必须放在顶层或嵌套在另一个 conditional‑group at‑rule 中。然而,浏览器也允许如下代码(至少在理论上并不合法):

.my-class {
  @supports (property: value) {
    /* … */
  }
}

这种行为令人困惑。浏览器要么完全忽略嵌套的 @supports(或者始终执行它,因为浏览器对 HTML 和 CSS 往往比较宽容),要么相对于它所在的规则来应用它。把它当作根级别规则来执行,却在视觉上嵌套在选择器内部,这会产生误导。

Example

li::marker {
  @supports (content: " - ") {
    content: " - ";
    color: red;
  }
}
  • Chrome、Safari 和 Firefox 都支持 ::marker,并且它们都支持 content: " - "
  • Safari 支持在 ::marker 中使用 content

使用上述代码时:

  • Chrome 和 Firefox 会渲染出红色的 “ - ”。
  • Safari 则渲染出一个红色的圆点。

令人困惑的是,@supports 条件会成功,即使该声明在特定上下文中实际上并不受支持。

Why This Happens

问题并不在于浏览器“移动”(更准确地说是“解析”)嵌套的 @supports 规则到顶层上下文,而在于 @supports 本身的定义。特性检查决定的是声明一般是否有效,而不是它在特定选择器或伪元素上下文中是否有效。

Possible Solutions

Extend @supports with Context‑Aware Checks

引入新的运算符或函数,使 @supports 能够验证组合而不是独立特性。例如:

@supports selector(::marker) and (content: " - ")

@supports selector(::marker) xand (content: " - ")

甚至是基于规则的检查:

@supports rule(::marker { content: " - " })

这些方式可以测试声明是否真的在给定的渲染上下文中起作用,而不仅仅是检查语法是否被识别。

Make Browsers Less Forgiving

一种不太理想的做法是让浏览器永不执行嵌套的 @supports 规则。但这会破坏依赖当前宽容行为的现有代码。

Workarounds

容器查询(container queries)和样式查询(style queries)有时可以作为变通方案,但它们目前仅部分支持,并且只能检查自定义属性,无法检查任意声明。虽然在某些情况下有帮助,但它们并未消除嵌套 @supports 带来的误导或局限性。

0 浏览
Back to Blog

相关文章

阅读更多 »

公开学习 | Day 0

第0天 更新日志 我已经完成了 Odin Project 的介绍和先决条件。在介绍中,我了解了 Odin Project 是什么,网页开发……