
本文详解如何通过纯 css + javascript 实现多页容器间的平滑过渡效果:当前页向左滑出并淡出,下一页从右侧滑入并淡入,避免 display 切换导致的动画中断问题。
本文详解如何通过纯 css + javascript 实现多页容器间的平滑过渡效果:当前页向左滑出并淡出,下一页从右侧滑入并淡入,避免 display 切换导致的动画中断问题。
要实现「当前页左滑淡出 + 下一页右滑淡入」的连贯动画,关键在于避免直接操作 display 属性——因为 display: none 会立即将元素从渲染树中移除,导致 CSS 过渡(transition)被强制中断,使 fade-out 失效或不可见。
正确的做法是:所有页面始终保留在 DOM 中且可见(display: block),仅通过 opacity、transform 和定位控制其视觉状态。以下是可直接运行的专业级实现方案:
✅ 核心思路
- 所有页面使用
position: absolute叠加在同一区域; - 初始时仅首页可见(
opacity: 1,transform: translateX(-50%)),其余页默认偏移至右侧(如left: 2000px); - 切换时:
- 当前页添加
.fade-out→opacity: 0+transform: translateX(-150%)(向左滑出); - 下一页添加
.fade-in→opacity: 1+transform: translateX(-50%)(居中浮现)。
- 当前页添加
? 完整代码示例
HTML 结构
<main><section id="0">第一页内容</section><section id="1">第二页内容</section><section id="2">第三页内容</section><section id="3">第四页内容</section></main><button id="nextBtn">→ 下一页</button>
CSS 样式(关键!)
main {
position: relative;
height: 200px;
overflow: hidden;
border: 1px solid #ccc;
margin: 1rem auto;
width: 600px;
}
section {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 100%;
padding: 1.5rem;
box-sizing: border-box;
text-align: center;
font-size: 1.2rem;
opacity: 0;
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); /* 更自然的缓动 */
}
/* 初始可见页(如第一页)需单独设置 opacity: 1 */
section:first-child {
opacity: 1;
}
.fade-out {
opacity: 0 !important;
transform: translateX(-150%) !important;
}
.fade-in {
opacity: 1 !important;
transform: translateX(-50%) !important;
}
button {
display: block;
margin: 1rem auto;
padding: 0.5rem 1.5rem;
font-size: 1rem;
cursor: pointer;
}
JavaScript 控制逻辑
let currentIndex = 0;
const totalSections = 4;
function fadeOutShowNext(currentId, nextId) {
const currentEl = document.getElementById(currentId);
const nextEl = document.getElementById(nextId);
// 移除可能残留的动画类
currentEl.classList.remove('fade-in');
nextEl.classList.remove('fade-out');
// 触发动画
currentEl.classList.add('fade-out');
nextEl.classList.add('fade-in');
}
// 绑定按钮事件
document.getElementById('nextBtn').addEventListener('click', () => {
if (currentIndex >= totalSections - 1) {
alert('已到最后一页!');
return;
}
fadeOutShowNext(currentIndex.toString(), (++currentIndex).toString());
});
⚠️ 注意事项
-
不要用
display: none/block控制显隐:它会破坏 transition 流程。动画应全程依赖opacity和transform(硬件加速,性能更优)。 -
!important的合理使用:在动画类中强制覆盖基础样式,防止初始opacity: 0被误覆盖。 -
过渡时间需一致:
.fade-out和.fade-in的transition-duration必须相同(如0.8s),否则会出现错帧。 -
z-index 可选优化:若页面内容重叠异常,可为
.fade-in添加z-index: 10确保层级优先。
✅ 效果验证
- 当前页平滑左滑出视野并渐隐;
- 下一页从右侧滑入中心位置并渐显;
- 无闪烁、无跳变、无 JS 阻塞,兼容现代浏览器。
此方案兼顾语义清晰性、动画流畅性与维护性,是单页多视图切换的工业级实践范式。










