滚动触发动画在Safari中播放完成后透明度降低,请问错误出在哪里?
问题根因
- 关键帧代码存在笔误:
slide-in-left相关关键帧的初始状态中,translateX(-5s0px)多了冗余字符s,Safari 对非法 CSS 属性值的容错处理逻辑和其他浏览器不同,会触发渲染异常。 - 同一
opacity属性被多个规则同时控制:.js-scroll类绑定了opacity的过渡效果,.scrolled类同时设置了静态opacity:1和带opacity控制的关键帧动画,属性优先级计算逻辑在 Safari 中存在 bug,导致最终渲染的透明度达不到 1。 - Safari 硬件加速合成逻辑缺陷:同时带过渡、动画属性的元素容易出现图层合成异常,导致半透明残留。
解决方案
按以下步骤修改代码即可修复问题:
- 修复关键帧笔误:将所有
@keyframes slide-in-left和@-webkit-keyframes slide-in-left中的translateX(-5s0px)替换为translateX(-50px)。 - 移除
opacity属性的重复控制:删除.js-scroll类中的opacity过渡规则,入场动画已经由关键帧控制,不需要额外过渡叠加。 - 新增 Safari 兼容性规则:给
.js-scroll元素添加强制 GPU 合成的属性,避免图层渲染异常。 - 可选兜底:给
.js-scroll.scrolled的opacity属性添加!important强制优先级,避免 Safari 属性计算错误。
修改后的核心代码示例
/* 调整后的js-scroll类 */ .js-scroll { opacity: 0; /* 触发GPU加速,避免Safari渲染异常 */ transform: translateZ(0); will-change: opacity, transform; /* 移除原有的opacity过渡规则 */ } /* 调整后的scrolled类 */ .js-scroll.scrolled { opacity: 1 !important; } /* 修复后的slide-in-left关键帧示例 */ @-webkit-keyframes slide-in-left { from { -webkit-transform: translateX(-50px); transform: translateX(-50px); opacity: 0; } to { -webkit-transform: translateX(0); transform: translateX(0); opacity: 1; } } @keyframes slide-in-left { from { -webkit-transform: translateX(-50px); transform: translateX(-50px); opacity: 0; } to { -webkit-transform: translateX(0); transform: translateX(0); opacity: 1; } }
如果修改后仍有问题,可以监听元素的 animationend 事件,动画结束后手动设置元素的行内样式 opacity: 1 兜底,代码示例如下:
// 新增动画结束监听逻辑 scrollElements.forEach(el => { el.addEventListener('animationend', () => { el.style.opacity = '1'; }) })
内容的提问来源于stack exchange,提问作者liska
相关产品推荐
相关产品推荐

