两个不同高度的绝对定位article标签淡入淡出切换问题
解决方案
解决这个问题的核心是让非激活状态的article既保留淡入淡出过渡效果,又不会因为自身高度撑开父容器的滚动范围。以下两种方案可以实现需求:
方法一:纯CSS静态方案
修改article的样式,给非激活状态的元素添加高度限制和溢出隐藏,激活时恢复正常显示,同时避免干扰页面交互:
html, body, main { height: 100%; } main { position: relative; height: 100%; width: 100%; overflow: auto; } body { background: pink; padding: 0; margin: 0; } .content { display: table-cell; vertical-align: middle } .container { max-width: 500px; margin: 0 auto; position: relative; overflow: hidden; } article { display: table; width: 100%; min-height: 100%; /* 激活时至少占满视口高度 */ background: no-repeat fixed bottom / cover; position: absolute; top: 0; left: 0; opacity: 0; z-index: -1; transition: opacity 0.3s ease; background-color: #fff; pointer-events: none; /* 非激活状态禁止交互 */ max-height: 0; overflow: hidden; /* 隐藏超出内容,避免撑开滚动条 */ } article.active { opacity: 1; z-index: 1; pointer-events: auto; /* 激活状态恢复交互 */ max-height: 1000vh; /* 足够大的值容纳所有内容 */ }
原理
- 非激活状态下
max-height: 0+overflow: hidden直接截断元素高度,不会影响父容器的滚动范围; pointer-events: none避免非激活元素干扰页面点击;- 仅对
opacity设置过渡,保证淡入淡出效果不受影响。
方法二:JS配合过渡结束事件
如果需要严格控制元素显示/隐藏的时机,可结合JS监听过渡结束事件,在淡出完成后再彻底隐藏元素:
修改后的JS代码
document.querySelector('#next').addEventListener('click', function() { const currentActive = document.querySelector('.active'); // 移除激活类,触发淡出过渡 currentActive.classList.remove('active'); // 监听过渡结束后隐藏元素 currentActive.addEventListener('transitionend', function handleEnd() { currentActive.style.display = 'none'; currentActive.removeEventListener('transitionend', handleEnd); }); const targetArticle = document.querySelector('#about'); // 先恢复显示,再触发淡入过渡 targetArticle.style.display = 'table'; // 强制触发重绘,确保过渡生效 void targetArticle.offsetWidth; targetArticle.classList.add('active'); });
对应CSS(保留原有过渡逻辑)
html, body, main { height: 100%; } main { position: relative; height: 100%; width: 100%; overflow: auto; } body { background: pink; padding: 0; margin: 0; } .content { display: table-cell; vertical-align: middle } .container { max-width: 500px; margin: 0 auto; position: relative; overflow: hidden; } article { display: table; width: 100%; height: 100%; background: no-repeat fixed bottom / cover; position: absolute; top: 0; left: 0; opacity: 0; z-index: -1; transition: opacity 0.3s ease; background-color: #fff; } article.active { opacity: 1; z-index: 1; }
原理
- 淡出过程完成后再设置
display: none,既保留过渡效果,又彻底移除非激活元素对滚动范围的影响; - 激活目标元素前恢复显示并触发重绘,确保淡入过渡正常执行。
内容的提问来源于stack exchange,提问作者Álvaro
相关产品推荐
相关产品推荐

