You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome中CSS animation导致filter滤镜过渡失效问题求解

问题现象

页面内设置了横向滚动动画的链接元素,默认应用grayscale灰度滤镜,预期鼠标悬浮时通过平滑过渡恢复彩色显示,但在最新版Chrome中出现如下异常:

  • 首次悬浮带动画的元素时,filter属性的transition过渡完全失效,直接瞬间跳转到无灰度状态,即使将悬浮态样式从filter: none改为filter: grayscale(0)也无法修复
  • 首次失效后短时间内反复移入移出鼠标,过渡效果会暂时恢复;如果鼠标移出时间较长,或是切换悬浮其他带动画的元素,过渡会再次失效
  • 同一代码在Firefox、Brave浏览器中运行正常,旧版Chrome也无此问题,属于Chrome新版本引入的渲染层缓存Bug
最小复现Demo

样式代码

.thing {
  background-color: red;
  width: 50px;
  height: 50px;
  
  filter: grayscale(1);
  transition: filter 1s;
}

.thing:hover {
  filter: none;
}

.broken {
  animation: move linear 10s infinite;
}

@keyframes move {
  0% {
    transform: translateX(0%);
  }
  50% {
    transform: translateX(500%);
  }
}

结构代码

<div class="broken thing">TEST1</div>
<div class="broken thing">TEST2</div>
<br>
<div class="thing">noanim</div>
<div class="thing">noanim</div>

上述代码中,不带broken动画类的元素悬浮过渡完全正常,带动画的元素会复现该Bug。

修复方案

该Bug的核心原因是Chrome对运行中transform动画的元素,没有正确缓存filter属性的初始过渡值,首次触发状态变更时直接跳变。可通过以下任意一种方案规避:

  • 强制为元素创建独立渲染层
    给带动画的元素添加will-change: filter声明,提示浏览器提前分配渲染资源、缓存filter属性状态,即可恢复正常过渡:
    .broken {
      will-change: filter;
      animation: move linear 10s infinite;
    }
    
    如果不想使用will-change,也可以通过transform: translateZ(0)开启硬件加速达到同样效果,但要注意避免页面过多独立层带来的性能损耗。
  • 拆分动画与滤镜的挂载节点
    不要把动画和filter属性加在同一个元素上:外层元素负责横向滚动动画,内层子元素负责灰度滤镜和过渡效果,从结构上绕开Chrome的渲染判断逻辑:
    <!-- 结构调整 -->
    <div class="broken">
      <div class="thing">TEST1</div>
    </div>
    
    /* 样式拆分 */
    .broken {
      animation: move linear 10s infinite;
    }
    .thing {
      width: 50px;
      height: 50px;
      background-color: red;
      filter: grayscale(1);
      transition: filter 1s;
    }
    .thing:hover {
      filter: grayscale(0);
    }
    

两种方案在当前最新版Chrome中测试均有效,不会影响其他浏览器的正常表现。


内容的提问来源于stack exchange,提问作者Stefan Todoran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:15:37