CSS 下拉菜单
导航栏把链接排成一行。下拉菜单则增加一个嵌套面板,在触发项下方展开 — 通常靠悬停,更好的做法是键盘焦点进入时也能打开。先掌握一个稳妥的 CSS 模式,再去发明巨型超级菜单。
下拉菜单工具箱
📊 下拉菜单一览
| 部件 | 日常作用 |
|---|---|
| Relative 触发器 | 父级 li(或包裹层)成为定位锚点 |
| Absolute 面板 | 嵌套菜单落在触发项下方(top: 100%) |
| 默认隐藏 | 打开前用 display: none 或移出屏幕 |
:hover 显示 |
指针打开面板 |
:focus-within |
键盘用户在 Tab 时也能打开/保持面板 |
z-index |
让打开的面板盖住后面的页面内容 |
纯 CSS 下拉是经典教学内容。真实产品常会加 JS 做触控点击切换、Escape 关闭和更完整的无访问性 — 先在这里学会 CSS 骨架。
Relative 触发器与嵌套列表
把触发链接留在顶栏,再嵌套第二层列表作为子菜单。父项必须定位,absolute 子元素才知道“家”在哪。
.nav > li {
position: relative;
}
.nav > li > a {
display: inline-block;
padding: 0.5rem 0.75rem;
}
触发项下方的 absolute 面板
用 position: absolute 放置子菜单,钉在触发项底部,并给实心背景,避免页面文字透过来。
.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);
}
打开前先隐藏
默认保持面板关闭。一开始就全部展开就失去了下拉的意义。
.nav .submenu {
display: none;
}
悬停时显示
指针停在父项上时显示面板。触发项上的 padding 有助于避免边缘误关。
.nav > li:hover > .submenu {
display: block;
}
也请加上 focus-within
只有 hover 会丢掉键盘用户。:focus-within 在焦点位于该项内部时保持面板打开 — 稳妥的 CSS 升级。
.nav > li:hover > .submenu,
.nav > li:focus-within > .submenu {
display: block;
}
稳妥的下拉习惯
Relative 父级、absolute 面板、默认隐藏、hover + focus-within、适度 z-index。点击切换的超级菜单和复杂 ARIA 留给更丰富的模式 — 别和扁平导航栏那一课搞混。
.nav .submenu {
z-index: 20;
}
.nav .submenu a {
display: block;
padding: 0.45rem 0.9rem;
text-decoration: none;
color: inherit;
}
自己试试
- 让每个顶级
li为position: relative。 - 嵌套
.submenu列表,并设为absolute; top: 100%; left: 0。 - 用
display: none隐藏,再在li:hover时显示。 - 加上
:focus-within,让键盘焦点也能打开面板。 - 提高
z-index,并写出何时要为触控点击切换加 JS。
常见错误
- Absolute 子菜单却没有 relative 父级(面板会跑飞)
- 默认就让子菜单可见
- 去掉焦点样式,键盘用户迷失方向
- 还没学会这套 CSS 骨架就做完整 JS 超级菜单
- 把下拉当成整页布局课
小结
- 下拉在 relative 触发器下嵌套面板
- Absolute +
top: 100%把菜单钉在链接下方 - 默认隐藏;用 hover 与 focus-within 显示
- 用 z-index 让面板盖住页面内容
- 扁平导航栏在前;嵌套菜单是本课
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部