如何在 Framer Motion 中逐字动画时保留单词间空格

1次阅读

如何在 Framer Motion 中逐字动画时保留单词间空格

本文详解如何在使用 framer motion 实现逐字动画(letter-by-letter)时,正确保留原始文本中的空格与排版结构,避免“web developer”被渲染为“webdeveloper”的常见问题。

本文详解如何在使用 framer motion 实现逐字动画(letter-by-letter)时,正确保留原始文本中的空格与排版结构,避免“web developer”被渲染为“webdeveloper”的常见问题。

在 React + Framer Motion 的逐字动画实践中,一个典型陷阱是:直接对字符串调用 text.split(”) 后映射渲染,虽能拆出每个字符(包括空格),但因 HTML 默认合并连续空白符(如空格、换行),且 作为块级或弹性子元素默认不保留空白语义,导致视觉上空格“消失”。

✅ 正确方案:保留空格的两种推荐方式

方案一:使用 whiteSpace: ‘pre’(推荐)

为每个 设置 CSS whiteSpace: ‘pre’,使其像

标签一样忠实保留所有空白字符(包括空格、制表符、换行)。同时需移除 jsX 中 {char} 周围的多余空白(即确保模板中无换行/缩进干扰):</p><pre class="brush:php;toolbar:false;">import { motion } from 'framer-motion';  type Props = {   text: string; };  function AnimatedText({ text }: Props) {   const characters = text.split('');    return (     <div className="flex">       {characters.map((char, index) => (         <motion.span           key={index}           initial={{ opacity: 0, y: 15 }}           animate={{ opacity: 1, y: 0 }}           transition={{ delay: 0.04 * index }}           style={{ whiteSpace: 'pre' }} // ? 关键:保留空格语义         >           {char}         </motion.span>       ))}     </div>   ); }  export default AnimatedText;

? 为什么用 而非

是块级元素,强制换行会破坏内联文本流;而 是内联元素,更符合文字排版逻辑。配合 whiteSpace: ‘pre’,既能保留空格,又保持水平排列。

方案二:将空格替换为  (兼容性更强)

若需兼容某些特殊样式环境(如部分 CSS-in-JS 库对 whiteSpace 支持不稳定),可预处理字符串,将普通空格 ‘ ‘ 替换为 HTML 不间断空格实体 ‘u00A0’(即  ):

const characters = text.split('').map(char =>   char === ' ' ? 'u00A0' : char );

再配合默认渲染即可(无需额外 CSS):

{characters.map((char, index) => (   <motion.span     key={index}     initial={{ opacity: 0, y: 15 }}     animate={{ opacity: 1, y: 0 }}     transition={{ delay: 0.04 * index }}   >     {char}   </motion.span> ))}

⚠️ 注意事项

  • 避免在 map 渲染中添加换行或缩进(如 n {char}n),这会引入额外空白节点,干扰布局;
  • 若文本含多个连续空格(如 “a b”),whiteSpace: ‘pre’ 会完整保留;而   替换仅处理单个空格,如需支持多空格,建议用正则 / /g 全局替换;
  • 动画容器(如外层
    )应设置 gap 或 margin 控制字间距,而非依赖空格——空格仅用于语义分隔,视觉间距建议由 CSS 精确控制。

    ✅ 总结

    保留单词间空格的本质,是让浏览器正确解析并渲染空格字符。whiteSpace: ‘pre’ 是最语义清晰、维护成本最低的解法;  替换则提供更广泛的兼容性兜底。二者均可无缝集成到现有 Framer Motion 动画逻辑中,无需修改动画配置,即可实现专业级的逐字文本动效。

text=ZqhQzanResources