Next.js 14中Framer Motion whileInView短文本动画失效问题
Next.js 14 + Framer Motion 文本揭示动画异常修复
问题现象
在采用App Router的Next.js 14项目中,基于Framer Motion实现文本进入视口时从隐藏到显示,同时绿色遮罩从左滑出的动画效果时,出现以下异常:
- 长文本
<p>标签动画正常触发:文本从隐藏转为可见,绿色遮罩同步滑动 - 短文本
<p>仅绿色遮罩动效生效,文本始终处于隐藏状态;开启overflow:hidden时短文本完全不可见,移除该属性虽能显示文本,但破坏动画的流畅性与视觉完整性 - 浏览器DOM显示:短文本的包裹
motion.div始终保持opacity:0; transform: translateY(75px)状态,未触发进入视口的动画逻辑
问题根源
- 父容器使用
width: fill-content,短文本容器高度过小,结合overflow:hidden属性,文本初始状态的y:75偏移会被完全移出容器可视区域,导致Framer Motion的视口检测逻辑无法正确识别元素已进入视口 - 绿色遮罩为绝对定位,不受父容器内容高度限制,因此能正常触发动画;但文本容器因被移出可视区,视口检测失效,始终停留在初始隐藏状态
修复方案
1. 调整父容器尺寸规则
修改Reveal组件的父容器样式,替换宽度规则并添加最小高度,避免短文本容器高度不足:
// components/Reveal.tsx <div style={{ position: "relative", width: "100%", // 替换fill-content为100%,配合子元素max-w-sm控制实际宽度 minHeight: "1.5em", // 为短文本预留基础高度,防止初始偏移完全移出容器 overflow: "hidden", }} >
2. 统一视口检测触发逻辑
使用useInView钩子将视口检测绑定到父容器,确保两个动画元素同步触发,避免子元素尺寸问题导致的检测偏差:
// components/Reveal.tsx "use client"; import { motion, useInView } from "framer-motion"; import { useRef } from "react"; type Props = { children: JSX.Element; }; export function Reveal({ children }: Props) { const containerRef = useRef<HTMLDivElement>(null); const isInView = useInView(containerRef, { once: true }); return ( <div ref={containerRef} style={{ position: "relative", width: "100%", minHeight: "1.5em", overflow: "hidden", }} > <motion.div variants={{ hidden: { opacity: 0, y: 20 }, // 减小初始y偏移量,保留动画同时避免短文本被完全隐藏 visible: { opacity: 1, y: 0 }, }} initial="hidden" animate={isInView ? "visible" : "hidden"} transition={{ duration: 0.5, delay: 0.25 }} > {children} </motion.div> <motion.div variants={{ hidden: { left: 0 }, visible: { left: "100%" }, }} initial="hidden" animate={isInView ? "visible" : "hidden"} transition={{ duration: 0.5, ease: "easeIn" }} style={{ position: "absolute", top: 4, bottom: 4, left: 0, right: 0, background: "green", zIndex: 20, }} ></motion.div> </div> ); }
3. 优化文本初始偏移参数
将文本初始y偏移从75调整为20,既保留动画的向上浮现效果,又避免短文本因偏移量过大被父容器overflow:hidden完全隐藏,确保视口检测能正确识别元素位置
内容的提问来源于stack exchange,提问作者Sulejman
相关产品推荐
相关产品推荐

