如何解决移动端导航菜单悬停时菜单项重叠、无法自动下移问题
解决方案:移动端汉堡菜单子菜单悬停不重叠,下方元素自动下移
问题核心是子菜单若使用绝对定位会脱离文档流,导致父菜单项高度无法随子菜单展开自适应,进而和下方菜单项重叠。以下是修改后的完整代码及关键调整说明:
修改后的完整代码
HTML
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>移动端汉堡菜单</title> <style> /* 基础样式重置 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; } /* 汉堡按钮样式 */ .hamburger { position: fixed; top: 20px; right: 20px; font-size: 30px; cursor: pointer; z-index: 1000; } /* 菜单容器 */ .menu { position: fixed; top: 0; right: -100%; width: 250px; height: 100vh; background-color: #333; padding-top: 60px; transition: right 0.3s ease; list-style: none; overflow-y: auto; } .menu.active { right: 0; } /* 菜单项样式 */ .menu li { position: relative; padding: 15px 20px; border-bottom: 1px solid #444; } .menu li a { color: #fff; text-decoration: none; display: block; } /* 子菜单样式 */ .submenu { display: none; list-style: none; background-color: #444; margin-top: 10px; margin-bottom: 10px; } .submenu li { padding: 10px 30px; border-bottom: none; } /* 悬停/激活时显示子菜单 */ .menu li:hover .submenu, .menu li.active-submenu .submenu { display: block; } /* 移动端适配 */ @media (max-width: 768px) { .menu li { cursor: pointer; } } </style> </head> <body> <div class="hamburger">☰</div> <ul class="menu"> <li><a href="#">首页</a></li> <li> <a href="#">产品</a> <ul class="submenu"> <li><a href="#" class="submenu-link">产品1</a></li> <li><a href="#" class="submenu-link">产品2</a></li> <li><a href="#" class="submenu-link">产品3</a></li> </ul> </li> <li> <a href="#">服务</a> <ul class="submenu"> <li><a href="#" class="submenu-link">服务1</a></li> <li><a href="#" class="submenu-link">服务2</a></li> </ul> </li> <li><a href="#">关于我们</a></li> <li><a href="#">联系我们</a></li> </ul> <script> // 汉堡菜单切换 const hamburger = document.querySelector('.hamburger'); const menu = document.querySelector('.menu'); hamburger.addEventListener('click', () => { menu.classList.toggle('active'); }); // 移动端点击展开/收起子菜单 const menuItems = document.querySelectorAll('.menu li:has(.submenu)'); menuItems.forEach(item => { item.addEventListener('click', (e) => { // 点击子菜单链接时不触发父菜单折叠 if (!e.target.classList.contains('submenu-link')) { item.classList.toggle('active-submenu'); // 关闭其他已展开的子菜单 menuItems.forEach(otherItem => { if (otherItem !== item) { otherItem.classList.remove('active-submenu'); } }); } }); }); </script> </body> </html>
关键调整说明
取消子菜单绝对定位
移除子菜单的position: absolute设置,让子菜单作为父菜单项的正常子元素占据文档流空间。父菜单项会随子菜单展开自动增高,带动下方所有菜单项下移,彻底避免重叠。子菜单显隐逻辑调整
默认用display: none隐藏子菜单,悬停或点击时切换为display: block,确保子菜单展开时完全融入菜单布局。添加移动端点击支持
移动端无鼠标悬停,通过JavaScript给带自菜单的父项添加点击事件,切换active-submenu类控制子菜单显隐,同时处理点击子菜单链接不触发父菜单折叠的逻辑。菜单容器添加滚动
给.menu加上overflow-y: auto,避免子菜单过多时超出视口,保证所有内容都能滚动查看。
修改后,无论桌面端悬停还是移动端点击,子菜单展开时下方菜单项都会自动下移,所有文本清晰可读。
内容的提问来源于stack exchange,提问作者Hannah De Guzman
相关产品推荐
相关产品推荐

