You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

CSS3全屏覆盖式嵌套菜单实现:基于现有代码的技术咨询

嘿,我来给你几个实用的方案,帮你在现有的全屏覆盖导航里实现嵌套菜单。结合你已有的代码,咱们一步步来落地:

方案1:基础二级嵌套菜单(CSS+轻量JS)

这个方案适合只需要二级菜单的场景,实现简单,依赖少。

修改后的HTML结构

首先给导航添加带子菜单的父项:

<div id="myNav" class="overlay">
  <!-- 关闭按钮 -->
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  
  <div class="overlay-content">
    <a href="#">首页</a>
    <!-- 带二级菜单的父项 -->
    <div class="dropdown-item">
      <a href="javascript:void(0)" onclick="toggleSubmenu(this)">产品中心</a>
      <div class="submenu">
        <a href="#">智能硬件</a>
        <a href="#">软件服务</a>
        <a href="#">解决方案</a>
      </div>
    </div>
    <a href="#">关于我们</a>
    <a href="#">联系我们</a>
  </div>
</div>

<!-- 导航触发按钮 -->
<span onclick="openNav()">&#9776; 打开导航</span>

补充CSS样式

给子菜单添加基础样式,区分层级:

/* 你原有的全屏导航样式 */
.overlay {
  height: 100%;
  width: 100%;
  display: none;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: rgb(0,0,0);
  background-color: rgba(0,0,0, 0.9);
}

.overlay-content {
  position: relative;
  top: 25%;
  width: 100%;
  text-align: center;
  margin-top: 30px;
}

.overlay-content a {
  padding: 8px;
  text-decoration: none;
  font-size: 36px;
  color: #818181;
  display: block;
  transition: 0.3s;
}

.overlay-content a:hover {
  color: #f1f1f1;
}

.closebtn {
  position: absolute;
  top: 20px;
  right: 45px;
  font-size: 60px;
}

/* 新增子菜单样式 */
.submenu {
  display: none;
  margin-top: 10px;
}

.submenu a {
  font-size: 28px; /* 用更小的字号区分层级 */
  padding: 6px 0;
}

/* 子菜单展开状态 */
.submenu.open {
  display: block;
}

更新JS逻辑

添加切换子菜单的函数,同时在关闭导航时重置所有子菜单状态:

function openNav() {
  document.getElementById("myNav").style.display = "block";
}

function closeNav() {
  document.getElementById("myNav").style.display = "none";
  // 关闭导航时收起所有子菜单,避免下次打开时状态残留
  document.querySelectorAll('.submenu').forEach(submenu => {
    submenu.classList.remove('open');
  });
}

// 切换子菜单展开/收起
function toggleSubmenu(trigger) {
  const submenu = trigger.nextElementSibling;
  submenu.classList.toggle('open');
}

方案2:支持多级嵌套+平滑动画

如果需要三级及以上菜单,或者想要更流畅的交互效果,可以用这个方案,通过max-height实现展开收起的平滑过渡。

优化后的CSS样式

替换子菜单的CSS,添加动画和多级菜单支持:

/* 原有样式保留,替换子菜单部分 */
.submenu, .sub-submenu {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease-out;
  margin-top: 10px;
}

.submenu.open, .sub-submenu.open {
  max-height: 600px; /* 根据菜单数量调整足够大的值 */
}

.submenu a {
  font-size: 28px;
  padding: 6px 0;
}

/* 三级菜单样式 */
.sub-submenu {
  margin-top: 5px;
}

.sub-submenu a {
  font-size: 22px;
}

多级菜单的HTML结构

<div class="dropdown-item">
  <a href="javascript:void(0)" onclick="toggleSubmenu(this)">产品中心</a>
  <div class="submenu">
    <a href="#">智能硬件</a>
    <div class="dropdown-item">
      <a href="javascript:void(0)" onclick="toggleSubmenu(this)">智能家居系列</a>
      <div class="sub-submenu">
        <a href="#">智能门锁</a>
        <a href="#">智能照明</a>
        <a href="#">智能安防</a>
      </div>
    </div>
    <a href="#">软件服务</a>
  </div>
</div>

通用的JS切换函数

这个函数可以支持任意层级的子菜单,还能自动关闭同级其他展开的菜单(可选):

function toggleSubmenu(trigger) {
  const targetSubmenu = trigger.nextElementSibling;
  // 关闭当前父容器下的其他展开子菜单(可选,避免多个菜单同时展开)
  const parentContainer = trigger.closest('.overlay-content, .submenu');
  parentContainer.querySelectorAll('.submenu.open, .sub-submenu.open').forEach(submenu => {
    if (submenu !== targetSubmenu) {
      submenu.classList.remove('open');
    }
  });
  targetSubmenu.classList.toggle('open');
}

// 保留openNav和closeNav函数不变

额外优化建议

  • 添加箭头提示:在带子菜单的父项后面加<span class="arrow">▼</span>,然后用CSS在展开时旋转箭头:
    .arrow {
      font-size: 24px;
      margin-left: 8px;
      transition: transform 0.3s;
    }
    .submenu.open ~ .arrow, .sub-submenu.open ~ .arrow {
      transform: rotate(180deg);
    }
    
  • 点击外部收起子菜单:可以监听全屏导航的点击事件,判断点击区域不是菜单项时收起所有子菜单。
  • 键盘导航支持:给菜单项添加tabindex,支持用方向键切换菜单,提升 accessibility。

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

火山引擎 最新活动