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

如何用CSS实现垂直侧边栏菜单点击li显示子菜单?

嘿,我懂你现在的困扰——本来想让「Country」选项点击后才展开国家列表,结果鼠标一悬停就自动弹出来了,完全不是预期的效果对吧?咱们来一步步把它改成点击触发的模式~

首先得明确问题根源:你的原代码应该是用了CSS的:hover伪类来控制子菜单的显示,所以鼠标一放上去就触发了。要改成点击触发,有两种常用方案,你可以根据需求选择:

方案一:纯CSS实现(无需JavaScript)

这个方法适合简单的静态菜单,不用写JS代码,只需要调整HTML结构和CSS逻辑:

修改后的HTML结构

我们需要加一个隐藏的复选框,把「Country」改成和复选框关联的<label>,这样点击label就相当于勾选/取消勾选复选框,再用复选框的:checked状态来控制子菜单显示:

<aside class="sidebar">
  <ul class="menu">
    <li class="menu-item">
      <!-- 隐藏的复选框,用来记录点击状态 -->
      <input type="checkbox" id="country-toggle" class="toggle-checkbox">
      <!-- 把原来的Country链接改成label,关联上面的复选框 -->
      <label for="country-toggle" class="menu-link">Country</label>
      <!-- 你的国家列表子菜单 -->
      <ul class="submenu">
        <li><a href="#">USA</a></li>
        <li><a href="#">Canada</a></li>
        <li><a href="#">UK</a></li>
      </ul>
    </li>
    <!-- 其他侧边栏菜单选项 -->
  </ul>
</aside>

修改后的CSS代码

把原来的:hover触发逻辑换成复选框的:checked状态,同时隐藏掉那个用来触发的复选框:

/* 隐藏复选框,只用来做状态记录 */
.toggle-checkbox {
  display: none;
}

/* 子菜单默认隐藏 */
.submenu {
  display: none;
}

/* 当复选框被选中时,显示对应的子菜单 */
.toggle-checkbox:checked + .menu-link + .submenu {
  display: block;
}

/* 可选:给label加个手型光标,提示用户这是可点击的 */
.menu-link {
  cursor: pointer;
}

方案二:JavaScript实现(更灵活)

如果你的菜单有更复杂的交互需求(比如点击其他地方自动关闭菜单、同时只能展开一个子菜单等),用JS会更合适:

保持原HTML结构(或小改)

可以保留你原来的HTML,只给「Country」的触发元素加个专属类名:

<aside class="sidebar">
  <ul class="menu">
    <li class="menu-item">
      <a href="#" class="menu-link country-trigger">Country</a>
      <ul class="submenu">
        <li><a href="#">USA</a></li>
        <li><a href="#">Canada</a></li>
        <li><a href="#">UK</a></li>
      </ul>
    </li>
    <!-- 其他侧边栏菜单选项 -->
  </ul>
</aside>

调整后的CSS

子菜单默认隐藏,加一个active类用来控制显示:

.submenu {
  display: none;
}

/* 当子菜单有active类时显示 */
.submenu.active {
  display: block;
}

添加JavaScript代码

通过点击事件切换子菜单的active类,实现点击展开/收起:

// 获取「Country」触发元素和对应的子菜单
const countryTrigger = document.querySelector('.country-trigger');
const submenu = countryTrigger.nextElementSibling;

// 给触发元素绑定点击事件
countryTrigger.addEventListener('click', function(e) {
  // 阻止a标签的默认跳转行为(如果用的是a标签的话)
  e.preventDefault();
  // 切换子菜单的active类,实现展开/收起
  submenu.classList.toggle('active');

  // 可选:添加点击页面其他地方自动关闭菜单的逻辑
  document.addEventListener('click', function closeMenu(e) {
    if (!countryTrigger.contains(e.target) && !submenu.contains(e.target)) {
      submenu.classList.remove('active');
      // 关闭后移除这个临时事件监听,避免重复绑定
      document.removeEventListener('click', closeMenu);
    }
  });
});

注意事项

  • 记得根据你自己实际代码里的类名、标签结构调整选择器,比如如果你的子菜单类不是submenu,要改成你自己的类名~
  • 如果用方案一,要确保<label>for属性和复选框的id完全一致,不然关联会失效。

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

火山引擎 最新活动