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

基于纯HTML&CSS实现子菜单根据空间自动上下动态定位

子菜单底部空间不足时自动向上显示的解决方案

问题

纯CSS实现的菜单-子菜单功能,鼠标悬停主菜单项时子菜单可正常展开,但当菜单位于页面底部时,子菜单会超出页面底部。需要实现:当底部可用空间不足时,子菜单自动切换为向上展开,根据空间自动调整位置。

现有代码

CSS

.main-item {
  list-style-type: none;
}

.main-item li:hover > ul.dropdown-menu {
  display: block;
}

.dropdown-submenu {
  position: relative;
}

.dropdown-submenu > .dropdown-menu {
  top: 0;
  left: 100%;
  margin-top: -6px;
}

.dropdown-item {
  padding: 0.5rem;
  cursor: pointer;
  background-color: #fff;
  color: #6c757d;
  border-color: #6c757d;
}

.dropdown-item:hover {
    background-color: #6c757d;
    border-color: #6c757d;
    color: #fff;
  }

HTML

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"/>
<ul class="main-item p-0">
  <li>
    <button type="button" class="btn-xs btn-outline-primary">Options</button>
    <ul class="dropdown-menu">
      <li class="dropdown-submenu dropdown-item dropdown-toggle">
        Menu 2
        <ul class="dropdown-menu">
            <li class="dropdown-item">1. sub-menu1</li>
            <li class="dropdown-item">2. sub-menu2</li>
            <li class="dropdown-item">3. sub-menu3</li>
            <li class="dropdown-item">4. sub-menu4</li>
            <li class="dropdown-item">5. sub-menu5</li>
            <li class="dropdown-item">6. sub-menu6</li>
            <li class="dropdown-item">7. sub-menu7</li>
            <li class="dropdown-item">8. sub-menu8</li>
            <li class="dropdown-item">9. sub-menu9</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

解决方案

这里提供两种可行的纯CSS方案,分别适配不同的浏览器兼容性需求:

方案1:利用CSS新特性实现自动空间检测(推荐现代浏览器)

通过:has和:in-view伪类检测子菜单是否超出视口,自动切换展开方向,无需固定子菜单高度:

.main-item {
  list-style-type: none;
}

.main-item li:hover > ul.dropdown-menu {
  display: block;
}

.dropdown-submenu {
  position: relative;
}

/* 默认向下展开,基于父元素底部定位 */
.dropdown-submenu > .dropdown-menu {
  position: absolute;
  left: 100%;
  bottom: 0;
  max-height: 80vh; /* 限制子菜单最大高度为视口80%,避免过度占用空间 */
  overflow-y: auto; /* 空间不足时显示滚动条 */
  transform: translateY(100%);
  margin: 0;
}

/* 当子菜单无法完全显示在视口内时,改为向上展开 */
.dropdown-submenu:has(.dropdown-menu:not(:in-view)) > .dropdown-menu {
  bottom: 100%;
  transform: translateY(-100%);
}

.dropdown-item {
  padding: 0.5rem;
  cursor: pointer;
  background-color: #fff;
  color: #6c757d;
  border-color: #6c757d;
}

.dropdown-item:hover {
    background-color: #6c757d;
    border-color: #6c757d;
    color: #fff;
}

方案2:兼容旧浏览器的固定高度方案

如果需要支持不支持:has伪类的旧浏览器,可以通过提前计算子菜单高度,结合媒体查询来切换展开方向:

.main-item {
  list-style-type: none;
}

.main-item li:hover > ul.dropdown-menu {
  display: block;
}

.dropdown-submenu {
  position: relative;
}

/* 默认向下展开 */
.dropdown-submenu > .dropdown-menu {
  position: absolute;
  left: 100%;
  top: 0;
  margin-top: -6px;
  /* 根据子项数量计算固定高度(每个子项高度约2rem,9个为18rem) */
  height: calc(9 * 2rem);
  overflow-y: auto;
}

/* 当视口高度不足以容纳子菜单向下展开时,切换为向上展开 */
@media screen and (max-height: calc(100vh - 18rem)) {
  .dropdown-submenu > .dropdown-menu {
    top: auto;
    bottom: 100%;
    margin-top: 0;
    margin-bottom: -6px;
  }
}

.dropdown-item {
  padding: 0.5rem;
  cursor: pointer;
  background-color: #fff;
  color: #6c757d;
  border-color: #6c757d;
}

.dropdown-item:hover {
    background-color: #6c757d;
    border-color: #6c757d;
    color: #fff;
}

方案说明

  • 方案1无需固定子菜单高度,适配更灵活,但需要浏览器支持:has(Chrome 105+、Firefox 121+、Safari 15.4+)和:in-view伪类。
  • 方案2通过固定高度和媒体查询实现兼容,适合旧浏览器环境,但需要根据实际子项数量调整高度值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:05:19