transition + transform 是最稳的组合;display 切换无法触发过渡,应使用 transform 和 opacity 实现硬件加速动画,避免 top/left 导致错位,移动端加 will-change 提升性能。

transition + transform 是最稳的组合
直接用 display 切换显隐无法触发 CSS 过渡,必须靠可动画属性。transform 和 opacity 是首选——硬件加速、性能好、兼容性高(IE10+)。别碰 top/left,滚动或缩放时容易错位。
实操建议:
- 初始状态设
transform: translateY(100%)(完全在视口下方) +opacity: 0 - 激活类里写
transform: translateY(0)+opacity: 1+transition: transform 0.3s ease, opacity 0.3s ease - 避免同时过渡太多属性,比如加
height或max-height,会导致重排、卡顿 - 移动端记得加
will-change: transform提前提示渲染引擎
用 @keyframes 做更复杂的入场动效
当需要弹跳、缩放、侧滑等非线性效果时,@keyframes 比 transition 更灵活。但注意:它不自动控制显隐,仍需配合 display 或 visibility 手动切换。
常见错误现象:
- 动画播完后元素突然“跳回”初始位置——没设
animation-fill-mode: forwards - 第一次点击无动画——因为初始
display: none导致元素未参与渲染,动画被跳过 - 解决方案:先设
display: block,再用setTimeout延迟 1ms 添加动画 class
dialog 元素的动画必须绕开 open 属性
<dialog></dialog> 的 open 属性是布尔值,本身不可动画。想加过渡,得把动画逻辑从属性切换移到 class 上。
使用场景:
- 检测支持性:
if ('showModal' in HTMLDialogElement.prototype) - 不支持时降级为
<div role="dialog"> + 手动管理 <code>aria-modal和焦点 - 统一用
.dialog--open类控制transform和opacity,而不是监听open变化 - 关闭时调用
dialog.close()后,再移除 class;别等close事件再删——动画会断掉 - 打开时设
document.body.style.overflow = 'hidden',但必须保存window.scrollY,关闭后window.scrollTo(0, savedY) - 弹层容器加
tabindex="-1"并在show后.focus(),否则键盘用户打不开 - ESC 键关闭必须监听
keydown,且只在弹层 visible 时生效,避免全局拦截干扰表单 - 移动端加
touch-action: manipulation防止 300ms 延迟导致点两下才响应
固定定位弹出层要防滚动穿透和焦点丢失
底部滑出、全屏遮罩这类 position: fixed 弹层,最容易被忽略的是交互完整性。
关键点:
display 还是 none,或者动画 class 被其他样式覆盖。调试时优先检查 computed style,而不是只看 classList。











