React+Tailwind实现Div平滑展开失效,求技术解决方案
问题
我想给包含输入元素的Div做平滑展开动画:初始时textarea尺寸小,输入框和按钮隐藏;点击Div后,显示输入框和按钮,同时把textarea的rows设为10、cols设为100,但现在只有尺寸突变,完全没有平滑过渡。试过framer motion,但和Tailwind CSS不兼容;给父Div加过渡类也没用,求解决办法。
相关代码:
JSX部分
<div ref={mainDivRef} className='z-10 flex justify-center flex-wrap flex-col gap-2 p-2 bg-slate-300 bg-opacity-30 rounded-md' onClick={() => handleClickInside()}> <textarea className='transition ease-in-out delay-150 resize-none rounded-md p-1 focus:outline-none' value={mainText} placeholder="Ask me something" rows={rows} cols={columns} onChange={(e) => setmainText(e.target.value)} /> {extraElements && <div className='transition-all ease-in-out duration-150 delay-150 inline-flex gap-3 min-w-full'> <input className='rounded-md p-1 grow focus:outline-none ' type="email" name="sender" id="senderText" placeholder='Your email' /> <button className='rounded-md p-1 bg-blue-200'>Send</button> </div> } </div>
处理函数
const handleClickInside = () => { setExtraElements(true) setRows(10) setColumns(100) props.blurBackground(true) }
展开效果:点击Div后,textarea直接从小尺寸跳到大尺寸,输入框和按钮瞬间出现,无任何平滑过渡动画。
解决方法
1. 用CSS尺寸过渡替代rows/cols属性
textarea的rows和cols是原生HTML属性,CSS过渡无法直接对它们做动画。改用height和width控制尺寸,结合Tailwind过渡类实现平滑变化:
- 初始给textarea设置固定小尺寸(比如
h-[40px] w-[200px]) - 展开后设置目标尺寸(比如
h-[200px] w-[800px]) - 保留
transition-all ease-in-out duration-300类确保过渡生效
2. 给额外元素加渐显+高度过渡
直接用{extraElements && ...}会导致元素瞬间显示,改用max-height和opacity组合实现平滑展开:
- 初始状态设置
max-h-0 opacity-0 overflow-hidden(隐藏且不占空间) - 展开后设置
max-h-[100px] opacity-100(根据实际内容调整max-h值) - 同样加过渡类保证动画流畅
修改后的完整代码
JSX部分
<div ref={mainDivRef} className='z-10 flex justify-center flex-wrap flex-col gap-2 p-2 bg-slate-300 bg-opacity-30 rounded-md' onClick={() => handleClickInside()}> <textarea className={`resize-none rounded-md p-1 focus:outline-none transition-all ease-in-out duration-300 ${ isExpanded ? 'h-[200px] w-[800px]' : 'h-[40px] w-[200px]' }`} value={mainText} placeholder="Ask me something" onChange={(e) => setmainText(e.target.value)} /> <div className={`inline-flex gap-3 min-w-full transition-all ease-in-out duration-300 ${ isExpanded ? 'max-h-[100px] opacity-100' : 'max-h-0 opacity-0 overflow-hidden' }`}> <input className='rounded-md p-1 grow focus:outline-none' type="email" name="sender" id="senderText" placeholder='Your email' /> <button className='rounded-md p-1 bg-blue-200'>Send</button> </div> </div>
处理函数(需新增状态isExpanded)
const [isExpanded, setIsExpanded] = useState(false); const handleClickInside = () => { setIsExpanded(true); props.blurBackground(true); };
关键说明
- 移除了原有的
rows和cols状态,改用isExpanded统一控制所有展开/收起状态 - 所有需要动画的元素都加上
transition-all类,确保尺寸、透明度等变化都有平滑过渡 max-height需设置一个比实际内容高度大的值,避免内容被截断
内容的提问来源于stack exchange,提问作者tangir miah
相关产品推荐
相关产品推荐

