原生 是标准答案,除非需要搜索、图标、分组或自定义面板样式;它原生支持 Tab 切换、方向键导航和屏幕阅读器识别,结构为 包含多个 ,通过 selected 和 disabled 属性控制默认项与禁用状态,多选需显式添加 multiple 属性。

原生 就是标准答案,别写 JS 模拟——除非你真需要搜索、图标、分组或自定义面板样式。
用 和 写最简下拉菜单
浏览器原生支持,不用 JS 就能 Tab 切换、方向键导航、屏幕阅读器识别。核心结构就是 包住一堆 。
-
的value是表单提交值,标签内文本是用户看到的内容 - 设默认项用
selected属性,不要多个selected,否则行为不一致 - 禁用整个下拉,加
disabled在上;只禁某一项,加disabled在对应 - 多选必须显式加
multiple属性,否则 Ctrl/Cmd + 点击无效
为什么点完就收起,但 JS 监听不到 change?
常见于移动端(尤其是 iOS Safari):点击后立即触发 change,但焦点还没稳定,或事件被冒泡打断。不是代码错,是时机问题。
- 监听
change事件,不是click——键盘操作(Tab + Arrow)不会触发 click - 避免在
外层套position: absolute且z-index过低,否则 iOS 可能截断下拉面板 - 如果用了
event.preventDefault()或阻止冒泡,会干扰原生行为,直接删掉 - 动态添加选项后,别用
innerHTML +=,改用selectElement.add(new Option("文本", "值")),防止焦点丢失
想改箭头、圆角、背景色?先看哪些能动
的样式能力极有限,强行硬改只会让 Chrome、Firefox、Safari 表现不一,iOS 上甚至失效。
- 安全可改:
width、padding、border、background-color、font、color - 基本不能动:下拉箭头位置/形状、展开面板样式、焦点环细节、滚动条(
::-webkit-scrollbar仅限 Chrome/Firefox) - 用
appearance: none去掉默认样式后,必须手动加padding-right预留图标空间,否则文字被截断 - 别设
height或line-height——Safari 下拉箭头会错位;推荐用box-sizing: border-box+ 显式height
真要深度定制?放弃 ,但别丢无障碍
带搜索、图标、分组、动画的下拉,原生 不适合。此时该用 + 模拟,但必须补全 ARIA 和键盘逻辑。
- 给按钮设
role="combobox"、aria-expanded、aria-controls - 每个选项用
,并同步aria-selected - 按
ArrowDown时调用e.preventDefault(),避免页面滚动;维护focusedIndex并主动focus() - 移动端优先用
touchstart响应,别等click(300ms 延迟) - 隐藏原生
用于表单提交,用visually-hidden类,再 JS 同步其value
最易忽略的点:键盘用户 Tab 进来时,下拉面板本身得有 tabindex="-1",否则焦点会跳进不可见区域。这不是锦上添花,是可用性底线。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











