Sticky粘性菜单故障:滚动复位后内容被顶部菜单遮挡
解决粘性菜单滚动回顶部时遮挡内容的问题
问题说明
我正在实现一个水平粘性菜单,页面滚动时菜单能固定在顶部,功能基本正常,但当页面滚动回初始位置时,菜单下方的内容会回到浏览器顶部,被顶部的粘性菜单遮挡。
原代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>TESTING</title> <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> <meta name="robots" content="noindex"> <meta name="googlebot" content="noindex"> <meta charset="utf-8"> <link href="Test2_main_new.css" rel="stylesheet" type="text/css"> <style> body{ position: relative; font-family: sans-serif; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"> </script> </head> <body> <div style="font-family: helvetica; margin: auto; height: 4060px; width: 100%; background-color: dimgrey;"> <div id="navbar"> <div class="menu"> <ul class="hamburger"> <li class="top"></li> <li class="middle"></li> <li class="bottom"></li> </ul> </div> <div> <img src="title.jpg" class="responsive" alt="#"> </div> </div> <div id="section1"> <a>Section 1</a> </div> <div id="section2"> <a>Section 2</a> </div> </div> </body> </html>
CSS
/*---HAMBURGER---*/ @charset "utf-8"; * {margin: 0px; padding: 0px;} div.menu{ width: 40px; margin-top: 20px; margin-right: 15px; margin-bottom: 15px; margin-left: 15px; cursor: pointer; float: left; } div.menu ul.hamburger{ list-style: none; } div.menu ul.hamburger li{ width: 40px; height: 5px; background: Black; margin-bottom: 5px; transition: all 300ms; } div.menu.check ul.hamburger li.top{ transform: rotate(-140deg) translateY(-13px); margin-left: 7px; } div.menu.check ul.hamburger li.middle{ opacity: 0; } div.menu.check ul.hamburger li.bottom{ transform: rotate(140deg) translateY(13px); margin-left: 7px; } /*---STICKY MENU---*/ #navbar { overflow: hidden; background-color: White; } #navbar a { float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px; text-decoration: none; } .content { padding: 16px; } .sticky { position: fixed; top: 0; width: 100%; } .sticky + .content { padding-top: 50px; } /*---TITLE---*/ .responsive { width: 100%; max-width: 45px; height: auto; float: right; margin: 14px; } /*---NAVIGATION LINKS---*/ a:link { color: #000; text-decoration: none; } a:visited { color: #000; text-decoration: none; } a:hover { color: #f1ac02; text-decoration: underline; } a:active { color: #000; text-decoration: none; } /*---NEW WORK CONDUCTED---*/ #section1 { background-color: white; width: 0 auto; height: 400px; margin: 20px; border: 1px solid black; } #section2 { background-color: white; width: 0 auto; height: 400px; padding: 20px; border: 1px solid black; }
JavaScript
<script> // When the user scrolls the page, execute myFunction window.onscroll = function() {myFunction()}; // Get the navbar var navbar = document.getElementById("navbar"); // Get the offset position of the navbar var sticky = navbar.offsetTop; // Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position function myFunction() { if (window.pageYOffset >= sticky) { navbar.classList.add("sticky") } else { navbar.classList.remove("sticky"); } } $('.menu').on('click', function () { $(this).toggleClass('check'); }); var acc = document.getElementsByClassName("accordion"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { this.classList.toggle("active"); var panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { panel.style.maxHeight = panel.scrollHeight + "px"; } }); } </script>
问题原因
- 原方案用JS给菜单添加/移除
fixed定位的sticky类,菜单变为fixed时会脱离文档流,此时通过.sticky + .content给内容加padding补偿空间,但实际内容并未使用.content类,导致补偿失效; - 滚动回顶部移除
sticky类时,菜单恢复static定位并重新占据文档流空间,页面布局重新计算,内容向上跳动后被菜单遮挡。
解决方案:使用CSS原生position: sticky
CSS原生sticky定位会在元素滚动到指定位置时固定,但不会脱离文档流,原本占据的空间会被保留,从根本上避免布局跳动和内容遮挡问题,实现更简洁可靠。
修改后的核心CSS
/*---STICKY MENU---*/ #navbar { position: sticky; /* 替换原有的overflow: hidden */ top: 0; /* 指定固定在顶部的位置 */ background-color: White; z-index: 100; /* 确保菜单在内容上方,避免被覆盖 */ overflow: hidden; /* 保留原有样式 */ }
移除JS中的粘性菜单逻辑
删除以下JS代码块,CSS已实现粘性效果:
window.onscroll = function() {myFunction()}; var navbar = document.getElementById("navbar"); var sticky = navbar.offsetTop; function myFunction() { if (window.pageYOffset >= sticky) { navbar.classList.add("sticky") } else { navbar.classList.remove("sticky"); } }
修改后的完整CSS
/*---HAMBURGER---*/ @charset "utf-8"; * {margin: 0px; padding: 0px;} div.menu{ width: 40px; margin-top: 20px; margin-right: 15px; margin-bottom: 15px; margin-left: 15px; cursor: pointer; float: left; } div.menu ul.hamburger{ list-style: none; } div.menu ul.hamburger li{ width: 40px; height: 5px; background: Black; margin-bottom: 5px; transition: all 300ms; } div.menu.check ul.hamburger li.top{ transform: rotate(-140deg) translateY(-13px); margin-left: 7px; } div.menu.check ul.hamburger li.middle{ opacity: 0; } div.menu.check ul.hamburger li.bottom{ transform: rotate(140deg) translateY(13px); margin-left: 7px; } /*---STICKY MENU---*/ #navbar { position: sticky; top: 0; overflow: hidden; background-color: White; z-index: 100; } #navbar a { float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px; text-decoration: none; } .content { padding: 16px; } /*---TITLE---*/ .responsive { width: 100%; max-width: 45px; height: auto; float: right; margin: 14px; } /*---NAVIGATION LINKS---*/ a:link { color: #000; text-decoration: none; } a:visited { color: #000; text-decoration: none; } a:hover { color: #f1ac02; text-decoration: underline; } a:active { color: #000; text-decoration: none; } /*---NEW WORK CONDUCTED---*/ #section1 { background-color: white; width: 0 auto; height: 400px; margin: 20px; border: 1px solid black; } #section2 { background-color: white; width: 0 auto; height: 400px; padding: 20px; border: 1px solid black; }
修改后的完整JavaScript
<script> $('.menu').on('click', function () { $(this).toggleClass('check'); }); var acc = document.getElementsByClassName("accordion"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { this.classList.toggle("active"); var panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { panel.style.maxHeight = panel.scrollHeight + "px"; } }); } </script>
效果说明
修改后,菜单会在页面滚动到顶部时自动固定,滚动回初始位置时,菜单恢复原位置,内容不会因布局变化跳动或被遮挡,同时保留原有的汉堡菜单和折叠面板功能。
内容的提问来源于stack exchange,提问作者maveric2theend
相关产品推荐
相关产品推荐

