近日,多位前端开发者在社交媒体和技术论坛上报告了一个令人困惑的CSS Bug——在某些特定条件下,CSS样式表中第一个声明的类选择器(class)会被浏览器完全忽略,不产生任何视觉效果。该Bug因其违背“层叠样式表”基本逻辑而引发热议,被戏称为“CSS的幽灵行为”。目前,部分浏览器厂商已承认此问题并着手调查。

现象重现:第一个类“消失”了

据海外开发者@css_wizardry在推文中描述,这个Bug在Chrome 120+及Edge 120+版本中均可稳定复现。一个典型的复现代码如下:

<style>
  .first { color: red; }
  .second { color: blue; }
</style>
<p class="first second">这段文字应该显示为红色</p>

按照CSS层叠规则,.first.second的优先级相同(均为类选择器,且出现顺序.first在前),<p>元素应显示红色。然而受影响的浏览器中,文字实际显示为蓝色,仿佛.first从未存在。更诡异的是,如果交换样式表中两个规则的顺序(.second在前,.first在后),颜色则正常变为红色。这意味着“在样式表文件或<style>块中第一条类声明总是被忽视”。

影响范围:非所有场景触发

进一步测试发现,该Bug并非无差别触发。它只发生在页面的首个<style>块或首个外部样式表中,且该样式表前几行没有任何其他选择器(如标签选择器或ID选择器)的情况下。一旦在第一条类声明之前添加任意一条非类规则(如body { }),Bug消失。此外,若使用<link>引入多个CSS文件,仅第一个CSS文件的第一条类声明受影响,后续文件中的规则不受影响。

原因分析:疑似CSS解析器索引越界

多位浏览器内核工程师在Chromium Bug Tracker中初步分析认为,问题根源可能出在CSS解析器的“第一规则缓存优化”上。现代浏览器为了提高渲染性能,通常会将样式表中第一条规则作为“快速命中入口”进行预解析。但某次优化提交(commit)中出现了一个边界条件:当该规则为类选择器时,解析器错误地将它标记为“待忽略”,转而直接匹配后续规则。这导致第一个类选择器虽然被Token化,但无法进入最终的匹配队列。

有趣的是,该Bug不会影响通过JavaScript动态插入的样式规则,也不影响:hover等伪类选择器。这说明问题特定于静态CSS解析的启动路径,而非运行时样式计算。

开发者反应:从困惑到应对

Bug曝光后,海外开发者社区迅速给出了多种临时解决方案:

  • 在样式表开头添加一个“空”标签选择器,如/* 临时修复 */ body { },将类选择器推到第二位。
  • 合并所有类规则到非首条位置,或将多个类选择器写成复合选择器(如.first.second)来避免顺序依赖。
  • 使用内联样式:where()伪类函数(优先级恒为0)也可绕开,但会增加维护成本。

知名CSS专家Lea Verou在社交平台评论:“这提醒我们,即便是最成熟的Web技术也可能隐藏着令人尴尬的低级Bug。好消息是,它容易被发现,也容易修复。”

浏览器厂商回应:确认并修复中

截至发稿时,Chrome团队已确认该Bug(Issue编号:#1389693)并标记为P0(最高优先级),计划在Chrome 121正式版及Edge 121中推出修复。Mozilla Firefox和Safari未受影响,因其CSS解析器实现机制不同。微软Edge团队同时表示,将同步上游修复补丁。预计受影响用户可在未来两周内通过浏览器自动更新获得修复。

对于无法立即升级浏览器的用户,建议使用上述临时方案,或通过<link>将样式表拆分为多个文件,确保第一个样式表内不包含关键类规则。

结语

一个小小的“首规则忽略”Bug,暴露了大型浏览器引擎在性能优化与正确性之间艰难平衡的现实。对前端开发者而言,这一事件再次证明了测试跨浏览器兼容性的必要性,也提醒我们:即便是“标准”的CSS,也永远值得多留一份心眼。随着修复补丁的推出,相信这个“幽灵Bug”很快就会成为历史。