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

如何实现hover时跑马灯平滑减速且避免transform元素偏移

问题根因
  • 移位核心诱因是hover状态下添加的transform-origin: top right:跑马灯动画全程用translateX做水平位移,默认变换原点是元素中心位置,hover时突然切换原点到右上角,浏览器会立刻基于新原点重新计算当前transform的渲染坐标,直接触发位置跳变。
  • 重复声明的transition规则存在逻辑冲突:hover块内先后写了三次transition,最后一条transition: transform 500ms ease-in-out 25ms会覆盖前面的配置,且transform属性正被关键帧动画持续驱动更新,给transform额外加过渡会和动画帧计算冲突,进一步加剧移位问题。
  • 直接修改CSS变量--animationTiming无法触发光滑的动画速率变化:关键帧动画不会对animation-duration的变量变化做自动补间,且原代码只放了一组内容,滚动到-50%位置时会出现空白断层,无法实现无缝效果。
修复后完整代码

HTML部分

<div class="wrapper">
<div class="track">
    <div class="content">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <!-- 追加第二组相同内容,实现无缝滚动衔接 -->
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
    </div>
</div>
</div>

SCSS部分

<style lang="scss">
    :root {
        --marquee-speed-normal: 100s;
        --marquee-speed-hover: 300s; // 数值越大滚动越慢,按需调整
    }

    .wrapper {
        position: relative;
        width: 100vw;
        max-width: 100%;
        height: 200px;
        overflow: hidden;
    }

    .track {
        position: absolute;
        white-space: nowrap;
        will-change: transform;
        // 仅给动画时长加过渡,实现平滑加减速,不要给transform加过渡避免和关键帧冲突
        transition: animation-duration 3s cubic-bezier(0.47, 0, 0.745, 0.715);
        animation: marquee var(--marquee-speed-normal) linear infinite;

        &:hover {
            animation-duration: var(--marquee-speed-hover);
        }
    }

    @keyframes marquee {
        from {
            transform: translateX(0);
        }
        to {
            transform: translateX(-50%);
        }
    }

    .content {
        display: flex;
    }

    .box {
        width: 500px;
        height: 200px; // 和容器高度匹配,避免不必要溢出
        background-color: red;
        border: 1px solid #000;
        flex-shrink: 0; // 防止flex布局下盒子被压缩
    }
</style>
修复说明
  • 全程移除transform-origin自定义配置,保持默认变换原点,从根源消除原点切换导致的位置跳变
  • 去掉冲突的transform过渡规则,仅对animation-duration属性加过渡,既不会打断关键帧的滚动逻辑,还能实现速率变化的平滑补间
  • 追加第二组重复内容,配合translateX(-50%)的动画终点实现无缝循环滚动,不会出现空白断层
  • 给box添加flex-shrink: 0避免flex布局下元素被压缩,调整box高度和容器匹配,消除多余溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:31:08