下拉菜单不必用<select>;导航类下拉应使用<nav><ul><li>结构配合CSS定位与JS交互,确保悬停、触控、键盘可访问及无障碍支持。

下拉菜单必须用 <select> 吗?
不是。网页下拉菜单 ≠ <select> 表单控件。多数导航栏里的“悬停展开”是纯 CSS + HTML 实现的,和表单无关。<select> 只适合表单提交场景(比如筛选分类),且原生不支持多级嵌套;而导航菜单需要鼠标悬停、键盘可访问、响应式收起等能力,得用 <nav> + <ul> + <li> 结构。
基础两级下拉菜单的 HTML + CSS 写法
关键在结构嵌套和 CSS 选择器联动。子菜单默认隐藏,父级 <li> 悬停时才显示:
<nav>
<ul>
<li><a href="#">首页</a></li>
<li class="dropdown">
<a href="#">产品</a>
<ul class="submenu">
<li><a href="/product/a">A系列</a></li>
<li><a href="/product/b">B系列</a></li>
</ul>
</li>
</ul>
</nav>
对应 CSS 要点:
-
.submenu必须设position: absolute,否则会撑开布局 -
.dropdown:hover .submenu触发显示,不能只写:hover .submenu(否则所有子菜单都会响应) - 加
top: 100%让子菜单紧贴父项底部对齐 - 父
<li>需要position: relative作为定位上下文
三级及以上怎么避免样式错乱?
每级子菜单都需独立定位上下文。常见错误是只给第一层 .dropdown 设 position: relative,导致二级菜单的子菜单(即三级)相对整个页面定位,飞出屏幕。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
正确做法是:每一级 <li> 都带 position: relative,且每级 .submenu 都用 top: 0; left: 100% 向右展开(横向多级)或 top: 100%; left: 0 向下展开(纵向多级):
- 二级菜单:父
<li class="dropdown">→.submenu向下展开 - 三级菜单:二级的
<li class="dropdown">→ 它的.submenu向右展开(或向下,视设计而定) - 所有
.submenu必须设display: none初始状态 - 用
.dropdown:hover > .submenu(注意>)防止深层嵌套误触发
移动端点击展开怎么兼容?
CSS :hover 在触摸设备上不可靠。必须加 JS 控制类名切换,同时兼顾键盘用户(Tab + Enter):
- 监听父
<a>的click和keydown(检测Enter或Space) - 点击时给父
<li>切换is-open类,CSS 改用.is-open > .submenu { display: block } - 别忘了点击空白处关闭:监听
document点击,排除菜单区域 - 为无障碍加
aria-expanded属性,值随展开/收起同步更新
多级菜单真正难的不是写几层 <ul>,而是定位上下文链、触控与键盘行为统一、以及 aria 属性的准确同步——漏掉任意一点,都会让部分用户根本用不了。


















