移动端下拉子菜单如何实现展开时向下推送其他列表项?
移动端导航子菜单覆盖问题解决方案
问题核心原因
你的移动端子菜单之所以会覆盖其他顶级项,是因为全局样式里给.sub-menu-content设置了position: absolute,绝对定位的元素会脱离正常文档流,不占用空间,自然无法推挤下方元素。而你测试的手风琴组件用的是静态/相对定位,属于文档流内元素,所以能正常推送。
具体修改步骤
1. 修正移动端子菜单定位
在移动端媒体查询(@media (max-width: 1025px))中,给.sub-menu-content添加position: static,覆盖全局的绝对定位,同时调整间距:
.sub-menu-content { position: static; /* 关键:让子菜单回到文档流 */ margin-top: 0; /* 覆盖全局的负margin */ padding:0; background-color: white; display: none; overflow: auto!important; box-shadow:none; border-radius:0; width:100%; }
2. 取消父项固定高度
移动端的.nav-item设置了固定height: 60px,子菜单展开后会被截断,改成自适应高度:
.nav-item { border-top: none; margin-left: 0; box-sizing: border-box; border-bottom: 1px solid #b5b5b5; width: 100%; text-align: left; line-height: 60px; /* 保留行高保证顶级项垂直居中 */ height: auto; /* 关键:自适应高度 */ display: block; }
3. 优化JS函数(支持多子菜单)
原来的函数依赖固定ID,改成基于点击元素的相对查找,避免ID冲突:
function subOpen(el) { // 找到当前点击元素的兄弟子菜单容器 const subMenu = el.parentNode.querySelector('.sub-menu-content'); subMenu.classList.toggle("show"); }
同时修改HTML中的点击事件:
<a onclick="subOpen(this)" class="sub-menu-link">link 1...
修改后的完整代码
HTML
<div class="header"> <div class="header-cont"> <div class="header-logo"> <a aria-hidden="true" href="/"> LOGO </a> </div> <nav class="header-nav"> <input type="checkbox" id="check"> <label for="check" class="checkbtn"> <div class="menu-btn"> <div class="menu-btn__burger"></div> </div> </label> <ul class="header-menu"> <li class="nav-item"> <div class="sub-menu"> <a onclick="subOpen(this)" class="sub-menu-link">link 1<svg class="drop-chevron" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg></a> <div class="sub-menu-content"> <ul> <li class="sub-item"><a href="#">sub link 1</a></li> <li class="sub-item"><a href="#">sub link 2</a></li> <li class="sub-item"><a href="#">sub link 3</a></li> <li class="sub-item"><a href="#">sub link 4</a></li> </ul> </div> </div> </li> <li class="nav-item"><a href="#" class="nav-link">link 2</a></li> <li class="nav-item"><a href="#" class="nav-link">link 3</a></li> <li class="nav-item"><a href="#" class="nav-link">link 4</a></li> </ul> </nav> </div> </div>
CSS
body { margin: 0; font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji; font-size: 1rem; font-weight: 400; line-height: 1.5; color: #333; background-color: #fff; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } a { text-decoration:none; } .header-cont, .nav-link { align-items: center; } .header-nav, .nav-item { height: 60px; } .header { background: #fff; box-shadow: 0 0 10px -3px rgb(0 0 0 / 50%); } .header-cont { display: flex; max-width: 1350px; margin: auto; justify-content: space-between; padding: 0 1rem 0 1rem; box-sizing: border-box; } .nav-link, .sub-menu-link { padding: 0 1rem 0 1rem; font-weight: 600; color: #0f0f0f !important; cursor:pointer; } .header-menu li:last-child { margin-bottom: 0; padding-bottom: 0; } .only-mobile { display: none !important; } .nav-item, .nav-link { display: inline-block; } .nav-item { line-height: 60px; } .drop-chevron { margin-left: 10px; height: 13px; fill: #0f0f0f; } .nav-item:hover svg { fill: #00007a !important; } .nav-item:hover { background-color: #00007a0d; transition: background-color 0.3s; } .nav-link:hover, .sub-menu-link:hover { color: #00007a !important; transition: 0.3s; text-decoration: none !important; } .sub-menu { position: relative !important; } .sub-menu-link { display: inline-block !important; text-decoration: none !important; } #check, .checkbtn { display: none; } .sub-menu-content { display: none; margin-top: -0.1rem; background-color: #fff !important; box-shadow: 0 6px 14px -1px rgb(0 5 20 / 15%); border-radius: 3px; overflow: hidden; position: absolute; width: 200px; z-index: 1000; } .sub-menu-content ul{ list-style-type: none; line-height: 30px; } .sub-item { width: 200px; margin-left: -0.5rem; } .sub-menu-content li:last-child { border-bottom: 1px solid transparent !important; padding-bottom: 0.1rem !important; margin-bottom: -0.2rem; } .sub-menu-content a { color: #0f0f0f; width: 100%; padding: 0.8rem; margin-left: -2rem; text-decoration: none; display: block; text-align: left; border-left: solid 4px transparent; } .sub-menu-content a:hover { text-decoration: none; border-left: 4px solid #ff9f1c; background-color: #00007a0d; color: #00007a !important; } .checkbtn { font-size: 20px; color: #00007a; float: right; line-height: 60px; margin-right: 1rem; cursor: pointer; } @media (max-width: 1025px) { selector .header-logo { margin-top: 0.1rem; padding-top: 0; } .header-cont { justify-content: space-between; } .only-mobile, .sub-menu-link { display: block !important; } .checkbtn, .nav-link, .sub-menu { display: block; } .drop-chevron { display: inline-flex; position:absolute; right:17px; top:22px; } .sub-menu-content { position: static; /* 新增:回到文档流 */ margin-top: 0; /* 覆盖全局负margin */ padding:0; background-color: white; display: none; overflow: auto!important; box-shadow:none; border-radius:0; width:100%; } .sub-item { border-top:none; margin-left:-1rem; margin-top:0rem; margin-bottom:0px; box-sizing: border-box; line-height: 3rem; border-bottom: solid 1px #B5B5B5; width:100%; } .sub-menu-content li:last-child { padding-bottom:0rem!important; margin-bottom:0rem; } .sub-menu-content a { color: #0f0f0f; width:100%; padding:5px; margin-left:0rem; text-decoration: none; display: block; border-left:none; } .sub-menu-content a:hover { text-decoration:none; border-left:none; background-color: #00007a0d; color:#00007a!important; } .header-menu { position: absolute; margin-top: 60px; width: 80%; height: 100vh; background: #e8e8e8; left: -100%; text-align: left; transition: 0.5s; margin-right: 0; padding: 0; box-shadow: rgb(18 18 18 / 8%) 4px 4px 12px 0; overflow:auto } .header-menu li:first-child { margin-top: 0; } .header-menu :last-child { padding-bottom: 0 !important; } .nav-item { border-top: none; margin-left: 0; box-sizing: border-box; border-bottom: 1px solid #b5b5b5; width: 100%; text-align: left; line-height: 60px; height: auto; /* 修改:自适应高度 */ display: block; } .nav-link:hover, .sub-menu-link:hover { background: #00007a0d; transition-duration: 0.25s; } #check:checked ~ ul { left: 0; } } .menu-btn { position: relative; display: flex; justify-content: center; align-items: center; width: 22px; height: 60px; cursor: pointer; transition: 0.5s ease-in-out; } .menu-btn__burger, .menu-btn__burger::after, .menu-btn__burger::before { width: 22px; height: 2.5px; background: #00007a; border-radius: 3px; transition: 0.3s ease-in-out; } .menu-btn__burger::after, .menu-btn__burger::before { content: ""; position: absolute; } .menu-btn__burger::before { transform: translateY(-6.5px); } .menu-btn__burger::after { transform: translateY(6.5px); } .menu-btn.open .menu-btn__burger { background: 0 0; box-shadow: none; } .menu-btn.open .menu-btn__burger::before { transform: rotate(45deg); } .menu-btn.open .menu-btn__burger::after { transform: rotate(-45deg); } /* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */ .show { display:block; } .active { color:#00007a!important; } @media(min-width: 1025px){ .sub-menu:hover .sub-menu-content { display: block; } }
JS
/* When the user clicks on the button, toggle between hiding and showing the dropdown content */ function subOpen(el) { const subMenu = el.parentNode.querySelector('.sub-menu-content'); subMenu.classList.toggle("show"); } // Close the dropdown menu if the user clicks outside of it window.onclick = function(event) { if (!event.target.matches('.sub-menu-link') && !event.target.closest('.sub-menu-content')) { var dropdowns = document.getElementsByClassName("sub-menu-content"); var i; for (i = 0; i < dropdowns.length; i++) { var openDropdown = dropdowns[i]; if (openDropdown.classList.contains('show')) { openDropdown.classList.remove('show'); } } } } //Mobile menu toggle code const menuBtn=document.querySelector(".menu-btn");let menuOpen=!1;menuBtn.addEventListener("click",()=>{menuOpen?(menuBtn.classList.remove("open"),menuOpen=!1,document.documentElement.style.overflow="scroll",document.body.scroll="yes"):(menuBtn.classList.add("open"),menuOpen=!0,document.documentElement.style.overflow="hidden",document.body.scroll="no")})
内容的提问来源于stack exchange,提问作者writable755
相关产品推荐
相关产品推荐

