关键在于用正确ARIA属性模拟原生select语义:触发按钮设role="combobox"和aria-haspopup="listbox";下拉容器设role="listbox"及aria-labelledby;选项用role="option"并动态管理aria-selected;配合aria-label/aria-valuetext提供清晰标签与实时反馈。
关键在于用正确的 ARIA 属性模拟原生 select 的语义和行为,让屏幕阅读器识别出“这是一个可展开的控件,当前有选中项,列表是它的选项集合”。
自定义下拉的触发按钮(比如那个带箭头的输入框或按钮)必须声明语义:
button 或 div 更准确)展开后的选项容器不能只是 div 包着一堆 div,要赋予明确角色:

role="menu" —— 它适用于右键菜单、应用菜单栏,不适用于表单选择场景列表里的每一项必须是独立的可选单元:
button 或 div
"false"(注意:不是用 CSS class 模拟,必须是真实属性)role="option" 上,并触发 aria-selected 切换aria-selected
屏幕阅读器需要知道“这是什么”以及“现在选了什么”:
aria-label="请选择城市"),或用 aria-labelledby 关联外部 label 元素aria-valuetext="已选择:北京市"),让屏幕阅读器在焦点离开前读出最新值不复杂但容易忽略:所有 ARIA 属性都要随交互动态更新,静态写死会导致语义失效。测试时用 NVDA + Firefox 或 VoiceOver + Safari,亲自用键盘操作一遍,听它怎么读。