最简下拉菜单用 select 和 option 即可实现,无需 JS/CSS;关键要设 name 属性、避免 value 为空、正确使用 selected/disabled;多选需 multiple 但移动端兼容差,导航类下拉应改用 ul/li 结构。

用 select 和 option 做最简下拉菜单
直接用原生 HTML 就能实现,不需要 JS 或 CSS 也能工作。关键就两个标签:select 是容器,option 是选项。
常见错误是漏掉 name 属性——没有它,表单提交时后端收不到值;或者把 value 写成空字符串却没加 disabled,导致“请选择”被当成有效提交项。
-
selected只能加在一个option上,加多个也只生效第一个 -
disabled加在option上,该项不可选且不参与提交;加在select上,整个控件禁用 - 中文标点(如全角冒号、引号)混入
value会导致后端解析失败,一律用英文字符
让下拉菜单支持多选:加 multiple 但要注意限制
select 加 multiple 属性确实能多选,但它不是“点击展开再勾选”的样式,而是直接显示为多行列表——这是浏览器原生行为,无法用 CSS 改成传统下拉弹层。
桌面端可用,但 iOS Safari 完全不支持:点击后只会弹出单选 Picker,multiple 被忽略。Android 表现也不统一,有的要长按才有反应,且无视觉反馈。
立即学习“前端免费学习笔记(深入)”;
- 必须用
select.selectedOptions获取选中项,别用select.value(它只返回第一个) - 设
size="1"可勉强维持单行外观,但滚动箭头仍存在,体验不一致 - 如果项目需兼容手机,必须放弃原生
multiple,改用div+checkbox的 JS 模拟方案
用 optgroup 分组提升可读性
当选项超过 5 个,用户扫一眼很难定位,用 optgroup 按逻辑分组能显著降低认知负担。它不是装饰,是语义化结构,对屏幕阅读器也有效。
注意 optgroup 的 label 属性值不能含 HTML 标签,也不能嵌套另一个 optgroup;里面放的 option 不能有 disabled 以外的交互属性。
-
optgroup自身不可选,它的label文字默认灰色,不能用 CSS 强行改成可点击色块 - 分组名别用模糊词如“其他”,应具体,比如“华东城市”“华北城市”
- 同一级
optgroup的顺序就是用户 Tab 键导航的顺序,别随意打乱
需要悬停/点击展开的导航式下拉?别用 select
select 天然不支持二级菜单、hover 展开、图标、搜索过滤等交互——它只负责表单数据采集。想做顶部导航栏那种“产品 → A系列 → B系列”的菜单,必须换结构。
正确做法是用 ul/li 嵌套,配合 aria-haspopup 和 aria-expanded 控制可访问性。纯 CSS 的 :hover 在手机上失效,必须用 JS 绑定 click 或 keydown(Enter/Space)事件。
- 别试图给
select套optgroup模拟层级,浏览器会把所有选项压平显示 - 移动端必须处理 touchstart 防止误触,且要支持键盘焦点进入子菜单
- 展开时记得关闭其他已开菜单,否则 DOM 中可能同时存在多个
display: block的子菜单
select 规范就行;后者从一开始就不该碰 select。混淆这两类场景,后面调试和适配的成本会指数级上升。



















