直接给弹窗加 animate-fade-in 类不会生效——Tailwind 默认不提供该类,需手动配置 keyframes 或使用 tailwindcss-animate 插件,并确保初始状态含 transition-opacity、opacity-0 和 pointer-events-none,显隐切换时配合 animationend 事件清理类。

直接给弹窗加 animate-fade-in 类不会生效——Tailwind 默认不提供这个类,必须手动配置动画帧并配合显隐逻辑才能实现真正平滑的淡入。
为什么 transition-opacity 单独用在弹窗上没反应
弹窗通常靠 hidden/block 或 opacity-0/opacity-100 控制显隐,但仅切换 opacity 类本身不触发过渡,除非:
-
transition-opacity和duration-300必须写在弹窗元素的**初始 class 列表中**(即首次渲染时就存在),不能等 JS 显示时才动态加上 - 起始态必须是
opacity-0且pointer-events-none(否则悬停/点击会误触) - 结束态必须是
opacity-100,且不能同时设hidden(hidden是display: none,会中断所有 transition) - 别用
visibility: hidden替代:它不触发重绘,opacity 过渡照样卡住
用 tailwindcss-animate 插件实现 fade-in 动画
这是最省心、语义最清晰的方式,但需确认插件已安装并启用:
- 安装插件:
npm install tailwindcss-animate - 在
tailwind.config.js的plugins数组中加入:require("tailwindcss-animate") - 弹窗容器加类:
animate-in fade-in duration-300(注意:不是animate-fade-in) - 关闭时用
animate-out fade-out duration-200,且必须配合onAnimationEnd事件清理 DOM,否则动画结束后元素还占位
纯 Tailwind 自定义 fade-in 动画(不依赖插件)
适合不想引入额外依赖的项目,核心是自己写 keyframes 并绑定到 animate 类:
立即学习“前端免费学习笔记(深入)”;
- 在
tailwind.config.js中扩展:keyframes: { fadeIn: { '0%': { opacity: '0', transform: 'scale(0.95)' }, '100%': { opacity: '1', transform: 'scale(1)' } } }, animation: { 'fade-in': 'fadeIn 300ms ease-out forwards' } - 弹窗默认状态加:
opacity-0 scale-95+transition-opacity duration-300 - JS 显示弹窗时,移除
opacity-0和scale-95,改加animate-fade-in(注意:不能同时保留 transition 类和 animate 类,会冲突) - 动画结束后立即移除
animate-fade-in,避免重复触发;可用el.addEventListener('animationend', () => el.classList.remove('animate-fade-in'))
移动端弹窗淡入要避开的坑
手机端没有 hover,但更关键的是:滚动穿透、焦点丢失、键盘遮挡都会让淡入效果显得突兀:
- 淡入期间禁止背景滚动:弹窗显示时给
html加overflow-hidden,隐藏时恢复 - 不要只靠 opacity 淡入——加轻微
scale(0.98 → 1)能显著提升“浮现感” - 如果弹窗内有 input,
focus()时机要卡在动画结束之后,否则 iOS 键盘弹出会打断动画 -
backdrop-blur或bg-black/50要和淡入同步,否则背景先糊/变暗,内容后出现,观感割裂
最易被忽略的一点:淡入动画是否连贯,不取决于你写了几个类,而取决于 DOM 状态是否真实变化——JS 插入弹窗节点后,必须等它完成挂载(比如用 requestAnimationFrame 延迟一帧),再添加动画类,否则浏览器可能跳过第一帧。


















