【发布时间】:2026-02-11 15:40:01
【问题描述】:
当在 Safari(桌面和 iOS)中使用 CSS transform 设置 @keyframes 并仅使用结束帧,然后以编程方式(通过 JS 内联)更新起始 transform 位置时,Safari 似乎继续执行动画从初始位置(即使用样式表中的初始变换值) - 不使用内联样式。
简而言之,Safari 关键帧动画似乎不会更新以反映以编程方式添加的内联样式的任何更改
下面的 sn-p(简化的测试用例)在 Firefox 和 Chrome 中都有效,但 Safari 只是动画到 0 的位置。我的问题是是否有解决方法?这是 Apple 对规范的预期表示,是否应该忽略关键帧动画的编程内联样式?我无法想象他们应该这样做。
我尝试克隆和替换元素,但无济于事。我还测试了包含 onLoad 的内联样式,并且这个 确实 在 Safari 中工作,因此该错误似乎仅在以编程方式添加样式时出现。
我很感激我可以完全使用 JS 和 requestAnimationFrame 制作动画,如果上述方法失败,这是我的后备解决方案。 (同样,一个很好的解决方案是使用Web Animation API,它似乎正是为此目的而设计的。但对此的支持不完整,所以暂时不支持)。我真正感兴趣的是上述错误的解决方案,而不是替代建议。
(顺便说一句,<marquee> 标签仍然可以作为跨浏览器解决方案... *颤抖*)
// Get slides
let marquee = document.querySelector('.mock-marquee__content');
// Transform slides for initial offset
marquee.style.transform = `translate(-${marquee.clientWidth}px, 0)`;
.mock-marquee {
overflow: hidden;
display: flex;
}
.mock-marquee__content {
white-space: nowrap;
display: flex;
animation: marquee 5s linear infinite;
}
.mock-marquee__content__slide {
display: block;
}
.mock-marquee__content__slide:not(:first-child) {
margin-left: 100px;
}
.mock-marquee__content:hover {
animation-play-state: paused;
}
@keyframes marquee {
from {
transform: translate(100vw, 0);
}
}
<div class="mock-marquee">
<div class="mock-marquee__content">
<span class="mock-marquee__content__slide">Hello</span>
<span class="mock-marquee__content__slide">world</span>
<span class="mock-marquee__content__slide">Foo</span>
<span class="mock-marquee__content__slide">Bar</span>
<span class="mock-marquee__content__slide">Bat</span>
<span class="mock-marquee__content__slide">Another one</span>
<span class="mock-marquee__content__slide">And another! Wowz</span>
</div>
</div>
【问题讨论】:
标签: css safari inline keyframe programmatically-created