You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现滑出式多级菜单中子菜单与父菜单同层级显示

滑出式多级菜单子菜单全屏高度实现方案

问题说明

我正在开发滑出式多级菜单,现在遇到一个问题——子菜单无法和父菜单处于同一层级。当父菜单项在第二、第三及更深层级时,打开子菜单后,它只和父菜单项同高度显示;我需要子菜单铺满整个视口高度,并且从页面顶部开始显示。

当前效果:
当前效果

期望效果:
期望效果

解决方案

核心问题是子菜单当前相对于父li元素定位,导致高度被父元素限制。我们需要修改CSS定位规则,让子菜单脱离父元素的约束,直接基于视口定位,同时保持和主菜单的布局对齐。

修改后的完整代码

HTML(无需修改)
<div class="menu-container">
  <div class="hamburger-menu">
    <span class="bar"></span>
    <span class="bar"></span>
    <span class="bar"></span>
  </div>
  <ul class="main-menu">
    <li><a href="#">Home</a></li>
    <li class="has-submenu">
      <a href="#">Services</a>
      <ul class="submenu">
        <li><a href="#">Service 1</a></li>
        <li><a href="#">Service 2</a></li>
      </ul>
    </li>
    <li class="has-submenu">
      <a href="#">About</a>
      <ul class="submenu">
        <li><a href="#">About 1</a></li>
        <li><a href="#">About 2</a></li>
      </ul>
    </li>
  </ul>
</div>
CSS(关键修改部分)
/* Hamburger menu icon styling */
.hamburger-menu {
  cursor: pointer;
}

.bar {
  display: block;
  width: 25px;
  height: 3px;
  margin: 5px 0;
  background-color: #333;
}

/* Main menu styling */
.menu-container {
  position: relative;
}

.main-menu {
  list-style: none;
  padding: 0;
  position: absolute;
  top: 50px; /* 可根据你的布局调整 */
  left: -250px; /* 初始状态隐藏在视口外 */
  width: 250px;
  background-color: #fff;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transition: left 0.3s ease;
  height: 100vh;
  z-index: 100; /* 确保主菜单层级正确 */
}

.main-menu li {
  padding: 10px;
  border-bottom: 1px solid #ddd;
  /* 移除父元素的relative定位,避免子菜单继承上下文 */
}

/* Submenu styling */
.submenu {
  display: none;
  position: fixed; /* 改为基于视口的fixed定位 */
  top: 0; /* 从页面顶部开始 */
  left: 250px; /* 与主菜单宽度对齐,接在主菜单右侧 */
  width: 250px;
  background-color: #f9f9f9;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  transition: opacity 0.3s ease;
  height: 100vh; /* 铺满视口高度 */
  z-index: 101; /* 确保子菜单在主菜单上方 */
  padding: 0;
  list-style: none;
}

.submenu li {
  padding: 10px;
  border-bottom: 1px solid #ddd;
}

/* 点击时显示子菜单 */
.has-submenu.open .submenu {
  display: block;
  opacity: 1;
}
JavaScript(微调交互逻辑)
document.addEventListener("DOMContentLoaded", function() {
  const hamburgerMenu = document.querySelector('.hamburger-menu');
  const mainMenu = document.querySelector('.main-menu');
  const menuContainer = document.querySelector('.menu-container');

  hamburgerMenu.addEventListener('click', () => {
    const isOpen = mainMenu.style.left === '0px';
    mainMenu.style.left = isOpen ? '-250px' : '0px';
    if (isOpen) closeSubmenus(); // 关闭主菜单时同步关闭子菜单
  });

  const submenuItems = document.querySelectorAll('.has-submenu');

  submenuItems.forEach(item => {
    item.addEventListener('click', (event) => {
      event.stopPropagation();
      const isOpen = item.classList.contains('open');
      if (!isOpen) closeSubmenus();
      item.classList.toggle('open');
    });
  });

  function closeSubmenus() {
    submenuItems.forEach(item => item.classList.remove('open'));
  }

  // 点击外部关闭菜单
  document.addEventListener('click', (event) => {
    if (!menuContainer.contains(event.target) && mainMenu.style.left === '0px') {
      closeSubmenus();
      mainMenu.style.left = '-250px';
    }
  });
});

关键修改点解析

  1. 子菜单定位方式:将.submenu的position从absolute改为fixed,使其脱离父元素约束,直接基于视口定位,实现从顶部开始、铺满全屏高度的效果。
  2. 移除父元素定位:删除.main-menu li的position: relative,避免子菜单继承父元素的定位上下文。
  3. 层级与布局对齐:设置z-index确保子菜单在主菜单上方,left: 250px与主菜单宽度保持一致,保证布局对齐。
  4. 交互逻辑优化:关闭主菜单时同步关闭所有子菜单,提升整体交互体验。

内容的提问来源于stack exchange,提问作者Julie R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 06:27:05