
本文详解如何在使用 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-in-JS 库对 whiteSpace 支持不稳定),可预处理字符串,将普通空格 ' ' 替换为 HTML 不间断空格实体 '\u00A0'(即 ): 再配合默认渲染即可(无需额外 CSS): 保留单词间空格的本质,是让浏览器正确解析并渲染空格字符。whiteSpace: 'pre' 是最语义清晰、维护成本最低的解法; 替换则提供更广泛的兼容性兜底。二者均可无缝集成到现有 Framer Motion 动画逻辑中,无需修改动画配置,即可实现专业级的逐字文本动效。 标签一样忠实保留所有空白字符(包括空格、制表符、换行)。同时需移除 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;
方案二:将空格替换为 (兼容性更强)
const characters = text.split('').map(char =>
char === ' ' ? '\u00A0' : char
);{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>
))}⚠️ 注意事项
✅ 总结










