正在加载...

CSS 下拉菜单

导航栏把链接排成一行。下拉菜单则增加一个嵌套面板,在触发项下方展开 — 通常靠悬停,更好的做法是键盘焦点进入时也能打开。先掌握一个稳妥的 CSS 模式,再去发明巨型超级菜单。

下拉菜单工具箱

📊 下拉菜单一览

部件 日常作用
Relative 触发器 父级 li(或包裹层)成为定位锚点
Absolute 面板 嵌套菜单落在触发项下方(top: 100%)
默认隐藏 打开前用 display: none 或移出屏幕
:hover 显示 指针打开面板
:focus-within 键盘用户在 Tab 时也能打开/保持面板
z-index 让打开的面板盖住后面的页面内容

纯 CSS 下拉是经典教学内容。真实产品常会加 JS 做触控点击切换、Escape 关闭和更完整的无访问性 — 先在这里学会 CSS 骨架。

Relative 触发器与嵌套列表

把触发链接留在顶栏,再嵌套第二层列表作为子菜单。父项必须定位,absolute 子元素才知道“家”在哪。

Relative 下拉项

css
.nav > li {
position: relative;
}

.nav > li > a {
display: inline-block;
padding: 0.5rem 0.75rem;
}

触发项下方的 absolute 面板

用 position: absolute 放置子菜单,钉在触发项底部,并给实心背景,避免页面文字透过来。

Absolute 子菜单面板

css
.nav .submenu {
position: absolute;
top: 100%;
left: 0;
min-width: 12rem;
margin: 0;
padding: 0.35rem 0;
list-style: none;
background: #fff;
border: 1px solid #e5e5e5;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
}

打开前先隐藏

默认保持面板关闭。一开始就全部展开就失去了下拉的意义。

默认隐藏子菜单

css
.nav .submenu {
display: none;
}

悬停时显示

指针停在父项上时显示面板。触发项上的 padding 有助于避免边缘误关。

悬停打开子菜单

css
.nav > li:hover > .submenu {
display: block;
}

也请加上 focus-within

只有 hover 会丢掉键盘用户。:focus-within 在焦点位于该项内部时保持面板打开 — 稳妥的 CSS 升级。

Focus-within 打开子菜单

css
.nav > li:hover > .submenu,
.nav > li:focus-within > .submenu {
display: block;
}

稳妥的下拉习惯

Relative 父级、absolute 面板、默认隐藏、hover + focus-within、适度 z-index。点击切换的超级菜单和复杂 ARIA 留给更丰富的模式 — 别和扁平导航栏那一课搞混。

打开菜单的层级

css
.nav .submenu {
z-index: 20;
}

.nav .submenu a {
display: block;
padding: 0.45rem 0.9rem;
text-decoration: none;
color: inherit;
}

自己试试

  1. 让每个顶级 li 为 position: relative。
  2. 嵌套 .submenu 列表,并设为 absolute; top: 100%; left: 0。
  3. 用 display: none 隐藏,再在 li:hover 时显示。
  4. 加上 :focus-within,让键盘焦点也能打开面板。
  5. 提高 z-index,并写出何时要为触控点击切换加 JS。

常见错误

  • Absolute 子菜单却没有 relative 父级(面板会跑飞)
  • 默认就让子菜单可见
  • 去掉焦点样式,键盘用户迷失方向
  • 还没学会这套 CSS 骨架就做完整 JS 超级菜单
  • 把下拉当成整页布局课

小结

  • 下拉在 relative 触发器下嵌套面板
  • Absolute + top: 100% 把菜单钉在链接下方
  • 默认隐藏;用 hover 与 focus-within 显示
  • 用 z-index 让面板盖住页面内容
  • 扁平导航栏在前;嵌套菜单是本课

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
7
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部