You need to enable JavaScript to run this app. 如何用CSS和JS实现居中句子词语替换的平滑过渡动画
优惠活动
大模型
产品
解决方案
定价
更多

如何用CSS和JS实现居中句子词语替换的平滑过渡动画

实现词语替换时的平滑宽度过渡效果

现有代码生硬跳变的原因

两个核心问题导致效果不流畅:

  • 动态切换的<span id="swappable">处于内容自动撑宽的状态(width: auto),这类由浏览器实时计算的尺寸,无法被CSS transition识别为可过渡的属性,宽度变化是瞬间完成的
  • 文本内容是直接硬替换的,没有任何过渡层次,左右两侧的文本会跟着突然变化的宽度直接跳转位置,没有缓冲

具体改造方案

要达成自然的平滑效果,核心是把“内容自动撑宽”转化为可控的、可触发过渡的固定数值宽度,搭配简单的文本淡入淡出动画,步骤如下:

  • 预先把所有待轮换的词语放到页面不可见的离屏容器里,同步和页面元素完全一致的字体样式,提前测量好每个词语的真实渲染宽度,避免切换时临时计算宽度导致的卡顿
  • 给动态切换的span配置宽度、透明度的CSS过渡规则,让宽度从旧值到新值的变化按照缓动曲线平滑移动
  • 切换文本时先淡出旧内容,等新内容替换、宽度过渡准备好之后,再淡入新文本,避免生硬的文本跳变

改造后的完整代码

调整后的HTML结构

<body>
    <h1>
        This animation is
        <span id="swappable">awesome</span>
        don't you think?
    </h1>
    <!-- 离屏测量容器,仅用于计算词语宽度,不影响页面布局 -->
    <span id="measure-container" style="position: absolute; visibility: hidden; height: auto; width: auto; white-space: nowrap;"></span>
</body>

调整后的CSS样式

body {
    display: flex;
    justify-content: center;
}

#swappable {
    display: inline-block;
    /* 宽度和透明度加平滑过渡,时长、缓动曲线可以根据视觉需求调整 */
    transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;
    text-align: center;
}

调整后的JavaScript逻辑

const swappables = ["awesome", "bad", "great", "fantastic", "boring"];
const swappableEl = document.getElementById("swappable");
const measureEl = document.getElementById("measure-container");

// 同步测量容器的字体样式,保证测量宽度和页面实际渲染宽度完全一致
const swappableStyle = getComputedStyle(swappableEl);
measureEl.style.fontFamily = swappableStyle.fontFamily;
measureEl.style.fontSize = swappableStyle.fontSize;
measureEl.style.fontWeight = swappableStyle.fontWeight;

// 提前计算每个词语的实际渲染宽度
const wordWidthList = swappables.map(word => {
    measureEl.textContent = word;
    return {
        word,
        width: measureEl.offsetWidth
    };
});

let index = 0;
// 初始化第一个词语的宽度,触发第一次渲染
swappableEl.style.width = `${wordWidthList[index].width}px`;

setInterval(() => {
    // 先淡出当前显示的文本
    swappableEl.style.opacity = 0;

    setTimeout(() => {
        // 轮换到下一个词语
        index = index >= swappables.length - 1 ? 0 : index + 1;
        // 替换文本内容
        swappableEl.textContent = wordWidthList[index].word;
        // 平滑过渡到新文本对应的宽度
        swappableEl.style.width = `${wordWidthList[index].width}px`;
        // 淡入新文本
        swappableEl.style.opacity = 1;
    }, 300);
}, 3000);

实际效果说明

  • 中间词语的宽度变化会沿着配置的缓动曲线慢慢收缩/展开,左右两侧的文本会跟着宽度变化的节奏平滑移动,不会出现生硬跳变
  • 文本本身的切换带有淡入淡出效果,视觉上更自然
  • 所有宽度都是提前测量好的,切换时不会出现布局计算导致的卡顿

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 12:15:06