下拉选择器(Dropdown menu)

2026年4月14日
学习小组
已累计原创 24 篇文章查看全部

当我打开一个注册页面,依次填完名字、邮箱和密码。到了"国家"这一栏时,输入框变成了一个灰色的矩形区域,右侧带一个向下的小三角图标。我点了一下,一个列表随即从这个区域下方展开,两百多个国家名纵向排列。我向下滚动找到 China 并点选,列表随即收回,"China"显示在矩形区域上。

这个控件就是下拉选择器(Dropdown menu),它可以把两百多个或是更多选项收进一个只占一行区域的组件里,点击展开,选完收回。

如果将这些选项全做成单选按钮平铺在页面上,整个页面将无法装下。可以说,下拉选择器用一次额外的点击换来了页面的整洁。

判断一个场景该不该选用下拉选择器,你只需关注两点即可:选项数量是否多到不适合平铺,以及选项之间是否互斥

五个以内的互斥选项,单选按钮直接平铺展示更好,用户一眼就能看到所有选择,不需要点击才能知道有哪些选项;超过五个时,平铺占据的面积会让页面变得臃肿,这时下拉选择器的空间效率优势就显现出来了。

如果选项之间不互斥、用户可以同时选中多个,那么此时需要将下拉框换为多选下拉或复选框组,而不是标准的单选下拉。


一、四种下拉选择器

1. 单选下拉

单选下拉是最基础的下拉形态。用户点击触发区域,选项列表展开,选中一个后列表收起,触发区域显示选中项。国家选择、省市选择、职业选择、语言偏好都是这种下拉框典型的使用场景,这些选项的共同点是选项固定、互斥、数量在五个到几十个之间。

单选下拉的选项数量有一个体感上的舒适区间,大约在 5 到 15 个之间。少于 5 个时,用户需要点击一次才能看到所有选项,不如使用单选按钮,将选项全部平铺直观;超过 15 个时,列表变长,用户不得不借助滚动选项来找寻目标,操作效率会有所下降。当选项在 15 到 40 个之间,列表仍然可用,但最好按字母或某种逻辑排序,以帮助用户快速定位。一旦超过 40 个——比如国家列表有两百多个选项——靠滚动浏览效率太低,必须加入搜索功能。

2. 可搜索下拉

可搜索下拉在触发区域或列表顶部内置了一个文本输入框,用户输入关键字后,选项列表就可以实时过滤,只显示匹配的结果。城市选择是最典型的使用场景。全国有几百个城市,用户不可能逐条翻找,输入"杭"立刻过滤出杭州,输入"she"能匹配出深圳和佘山。字体选择器也是同样的逻辑,设计工具里字体列表可能有几百项,此时输入字体名称的前几个字母,能马上定位想要找的字体。

可搜索下拉的搜索逻辑需要考虑容错。用户可能输入拼音、可能输入汉字、也可能只记得名称的一部分。如果搜索只支持精确匹配前缀,用户输入"州"就找不到"杭州",这种体验会很糟糕。设计时需要和开发明确搜索的匹配规则:是否支持拼音、是否支持模糊匹配、是否支持中间字符匹配。

4. 多选下拉

多选下拉支持用户从列表中勾选多个选项,选中的内容通常以标签(Tag)的形式排列在触发区域内。标签分类是典型的使用场景。一篇文章可以同时属于"设计""教程""工具"三个分类,用户需要在同一个下拉列表里勾选多个。权限分配也是同样的模式,给一个用户角色分配多项权限,权限列表可能会有十几项,逐条勾选后以标签形式展示已选内容。

多选下拉有一个容易忽略的问题。当选中项很多时,标签会把触发区域撑高,甚至撑成好几行,挤压下方的表单空间。设计时需要决定触发区域是否有最大高度限制。如果限制了高度,超出部分的标签该怎么处理——截断后显示"+3"这样的数量提示,还是让触发区域支持内部滚动?两种方案各有取舍,但必须在设计阶段确定,不要留给开发自行决定。

5. 分组下拉

分组下拉会在选项列表中用分隔线或小标题把选项按类别归拢。时区选择是典型的应用场景。几十个时区按洲分组(亚洲、欧洲、美洲),用户先定位到自己所在的洲,再在该组内找到具体时区。文件格式选择也经常分组:图片格式(PNG、JPG、SVG)一组,文档格式(PDF、DOCX)一组,数据格式(CSV、JSON)一组。

试想一下,将 30 个时区平铺在一个长列表里,用户得从头扫到尾才能找到目标。分组可以把这些选项按类别归拢后,用户的视线可以直接跳到"亚洲"那一组,搜索范围从原来的 30 个直接缩小到五六个。分组标题本身不可选中,只起到导航的作用。如果分组后每组内的选项仍然很多,那么可以考虑把分组下拉和搜索能力组合使用。


二、下拉选择器的构成

1. 触发区域

触发区域是指用户直接看到和操作的那个矩形框,未选择选项时显示占位提示文字,选中选项后显示当前选中项。

触发区域的宽度需要能够容纳最长的选项文字。如果选项里最长的一条是"中华人民共和国澳门特别行政区",而触发区域只给出了 120px 行宽,那么用户选中这个选项后,文字会被截断,进而无法确认自己选的到底对不对。设计时需要预估选项的最大文本长度,确保触发区域的宽度足以完整显示选项名称,如果因排版限制无法扩展触发区域宽度,可以考虑在触发区域设计 tooltip ,让用户通过鼠标悬停,查看完整内容。

触发区域的高度同样需要注意。在桌面端,标准表单控件的高度通常在 36px 到 44px 之间,和文本输入框保持一致,视觉上处于同一条基线。在移动端,触控目标的最小尺寸是 44pt(iOS)或 48dp(MD3),触发区域的高度不能低于这个值,否则用户的手指很难准确命中。

2. 下拉箭头

下拉箭头位于触发区域的右侧,通常是一个向下的小三角或 chevron 图标。这个图标是引导用户"这里可以展开"的视觉信号。没有箭头的触发区域看起来和普通文本标签没有区别,用户不会意识到这里可以点击。列表展开后,箭头通常会旋转 180 度变为向上,向用户传达"再次点击可以收起"的信息。这个旋转动画虽然细小,但它提供了状态反馈,用户可借助这种反馈,判定控件当前是展开还是收起。

3. 占位文本

占位文本在用户尚未做出选择时显示在触发区域内,用来向用户传达选择任务是什么。"请选择国家""选择你的职业""无"等,都是常见的占位文本。占位文本的颜色通常比正式选中的文字浅一档,用灰色或次要文字色,以此帮助用户界定"还没选"和"已经选了"两种状态。

占位文本很容易被误用来替代标签,但两者的作用不同。标签是这个表单字段的名称,比如"国家"二字;占位文本是字段内部的引导提示,比如"请选择国家"。两者必须同时存在。只靠占位文本充当标签会导致一个问题。用户选中某个选项后,占位文本被替换成选中项,标签信息随之消失,用户回头检查表单时想不起这个字段当初填的是什么。

4. 选项列表

选项列表是点击触发区域后展开的面板,包含所有可选项。列表的宽度通常和触发区域保持一致,有时也会比触发区域更宽以容纳较长的选项文字,但尽量不要比触发区域窄。窄了会让用户产生列表和触发区域不是一体的错觉。

列表的最大可见高度需要有限制。如果有 200 个选项,列表不能让200 行选项同时展示,那样会覆盖整个页面。所以通常设定一个最大高度(比如显示 6 到 8 个选项),选项数量超出的部分,用户可以通过列表内滚动进行访问。同时可以通过在列表旁边出现滚动条,或底部出现渐变阴影来引导用户下面还有更多选项。

5. 选项项

选项项是列表中的选项内容。最常见的选项项只包含文字,但也会根据场景不同,增加新的内容,比如前置图标(国旗图标放在国家名称左侧)、描述文字(主标题下方用小字补充说明)、或状态标记(对勾表示当前选中项)等。选项项之间通常不会设置分隔线,只依靠行间距和悬停高亮来区分每一项的边界。

选项项的高度在桌面端通常是 36px 到 40px,移动端至少 44pt 或 48dp,以保证手指能准确点击。选项项之间的间距过大会浪费列表空间、无形中增加滚动量,过小则容易产生误触,比如在移动端,很容易出现点错相邻的选项的情况。

6. 分组标题

分组标题只在分组下拉中出现,通常用加粗的文字或不同颜色标识,它和普通选项项在视觉上有明确的区分。分组标题不可点击、不可选中,鼠标悬停时不应该出现高亮效果。如果分组标题的交互状态和普通选项一样,用户会尝试点击它,如果没反应,会以为控件出了问题。

7. 搜索框

搜索框只在可搜索下拉中出现,位置通常在选项列表的顶部,列表展开时搜索框自动获得焦点,用户可以直接打字过滤。搜索框需要固定在列表顶部不随选项滚动而移动,如果滚动,用户想要修改搜索关键字,就不得不滚回顶部。



三、交互细节

下拉选择器有五种交互状态。

1. 默认状态

默认状态下,触发区域显示占位文本或上次选中的选项值,下拉箭头朝下,视觉权重和周围的表单控件保持一致。触发区域的边框通常是 1px 的浅灰色实线,和文本输入框的默认边框风格保持统一。

2. 悬停状态

悬停状态常见于桌面端,鼠标移入触发区域时,边框颜色加深或出现轻微的背景色变化,以告知用户"这个控件可以交互"。悬停状态的变化要足够明显,但不能过于强烈,否则会和界面其他元素抢夺视觉焦点。移动端没有悬停状态,因为手指触控没有"悬停"这个中间阶段。

3. 聚焦状态

聚焦状态在指用户通过 Tab 键导航到下拉选择器时出现的一种交互状态。此时触发区域的边框会变为主题色,宽度从 1px 加粗到 2px,和文本输入框的聚焦样式保持一致。用户用键盘操作时,如果聚焦后没有明显的视觉变化,那么他就不知道当前焦点在哪个控件上,按回车键时也会不确定展开的是不是自己想要操作的那个下拉框。

4. 展开状态

在展开状态下,选项列表弹出,下拉箭头旋转 180 度朝上,触发区域的边框保持聚焦时的主题色。

列表在弹出时,需要有动画过渡,通常是选项面板会从触发区域下方向下展开,持续 150ms 到 200ms。没有动画的面板弹出,会让用户感到突兀,但超过 300ms 的动画会让操作人员感觉响应迟缓。

列表展开后,当前选中项(如果有的话)需要在列表中高亮显示,通常的处理方法是将背景色加深或左侧显示一个对勾。用户打开列表时,列表应该自动滚动到选中项的位置,而不是每次都从第一项开始显示。如果上次选中的是列表中的第 45 项,那么下一次打开列表后却发现还是从第 1 项开始显示,用户就不得不重新往下翻,这种体验会很差。

列表展开的方向默认向下。但如果触发区域位于页面底部,向下展开会让列表超出可视区域,这时列表需要自动转为向上展开。设计时需要明确告诉开发这个翻转逻辑:当触发区域下方的可视空间不足以容纳列表的最大高度时,列表改为向上弹出,下拉箭头相应地调整方向。

5. 已选状态

已选状态下,列表收起,触发区域的占位文本被替换为选中项的内容,文字颜色从占位文本的灰色变为正文的深色。如果设计中有"清除选择"的需求,触发区域右侧会出现一个小叉号,点击后恢复到未选择的默认状态。叉号和下拉箭头需要有足够的间距,以避免用户想展开列表却误点了清除。

6. 禁用状态

禁用状态下,触发区域整体变灰,边框、文字、下拉箭头的颜色都要降低对比度,鼠标悬停时,不要出现悬停效果,点击后不要有任何响应。禁用状态的视觉变化要明显。如果只是把边框从深灰变成浅灰,用户很难察觉差异,进而在尝试多次点击后,以为系统出了问题。

7. 错误状态

错误状态在表单验证失败时出现,触发区域的边框变为红色,下方出现红色的错误提示文字,比如"请选择一个国家"。错误状态通常和必填验证想配合。用户提交表单时如果必填的下拉选择器没有选值,触发区域进入错误状态,以提示用户补选。


四、键盘交互

下拉选择器必须能够支持完整的键盘操作,这不只是无障碍访问的要求,也是桌面端高效操作的需要。表单填写时,用户习惯用 Tab 键操控光标,在各个字段之间跳转,如果跳到下拉选择器时,必须换成鼠标才能操作,那么工作流就会被打断。

聚焦状态下按回车键或空格键可展开列表。列表展开后,点击上下箭头键,可以在选项之间移动高亮焦点,每按一次移动一项。高亮焦点移动到列表顶部后,继续按上箭头时,焦点应该停在第一项不动,而不是跳到最后一项。

循环跳转在短列表里可能会很方便,但在长列表里用户会失去方位感。按回车键可选中当前高亮的选项并收起列表。按 Esc 键不做任何选择、直接收起列表,如果之前有选中,那么恢复到之前的选中值。

还有一个经常被忽略的键盘操作行为:字母键快速跳转。用户在列表展开时直接按键盘上的字母,高亮焦点会跳到第一个以该字母开头的选项。在国家列表里按"C",焦点跳到 Canada 或 China(取决于排序);再按一次"C",跳到下一个以 C 开头的国家。这个功能在长列表里能大幅提升定位效率,但很多设计方案里没有体现,开发也就没有同步实现。

1. 收起列表的触发方式

列表展开后,以下操作都应该可以触发列表收起:

  • 第一种:选中一个选项、按 Esc 键
  • 第二种:点击列表和触发区域以外的页面任意区域。
  • 第三种方式叫"点击外部关闭",是用户对弹出层的基本心理预期。弹出的东西,用户点别的地方就应该消失。如果点击页面空白处列表不收起,用户会感到被困在当前的下拉选择器里了。

2. 移动端的交互差异

在移动端,下拉选择器的交互与桌面端比,有两个不同。

第一个不同是触发方式。桌面端是鼠标点击,移动端是手指点按。点按的精度远低于鼠标点击,所以触发区域的高度必须保证至少 44pt(iOS)或 48dp(Android),并且相邻的表单控件之间要留足间距,避免用户点按时误触到相邻的输入框或按钮。

第二个不同是选项列表的呈现方式。桌面端的选项列表是一个紧贴触发区域的小面板,选项在列表内滚动。移动端屏幕空间有限,这种小面板在手机上操作体验很差:列表宽度受限、手指容易误触、滚动区域太小。iOS 和 Android 各自有原生的选择方式来替代桌面端的下拉面板。

iOS 传统上使用底部弹出的滚轮选择器(Picker),用户上下滑动滚轮来定位目标选项。iOS 15 之后也支持以弹出菜单(Menu)的形式展示选项列表,视觉上更接近桌面端。

Android 通常使用底部弹出的列表对话框。在移动端设计下拉选择器时,我们应该优先使用平台原生的选择组件,而不是把桌面端的下拉面板直接搬到手机上去。


五、平台差异

iOS 为处理"从一组选项中选一个选项",提供了两种控件。

第一种是 Pop-up Button(弹出式按钮)。用户点击后弹出一个选项菜单,菜单中当前选中项旁边有对勾标记,选中新的选项后菜单收起,按钮标题更新为选中项的内容。Pop-up Button 的行为和桌面端的下拉选择器最接近:选项互斥、点击展开、选一个收起。它适合选项数量在 5 到 15 个之间的场景,比如排序方式(最新、最热、最近编辑)、显示密度(紧凑、标准、宽松)等。

第二种是 Picker(选择器),这是 iOS 上标志性的滚轮界面。一列或多列可滚动的滚轮从屏幕底部弹出,用户通过上下滑动滚轮来定位目标选项,滚轮中央的高亮行就是当前选中的值。日期选择器是最常见的多列 Picker,年、月、日各一列,用户分别滚动三列来组合出一个完整日期。双列 Picker 也很常见,比如倒计时的小时和分钟选择。

Picker 的优势在于它是全屏模态的,弹出后占据屏幕底部的固定区域,不存在"列表遮挡其他内容"或"列表被页面边界截断"的问题。但滚轮每次只能看到五六个选项,如果选项有几十个,用户需要反复滑动才能找到目标。因此 Picker 适合选项数量中等且用户大致知道目标位置的场景(比如日期选择时用户知道自己要选几月),不适合选项很多且用户没有明确目标的场景(比如从 200 个国家里找一个)。

iOS 15 之后,Apple 引入了 Menu 形式的选项展示,视觉上是一个从触发区域弹出的浮动卡片,选项以列表形式排列,支持分组和分隔线。

Menu 的交互更接近桌面端的下拉体验,适合选项数量适中、不需要滚轮式浏览的场景。设计时我们可以根据选项数量和用户的操作习惯在 Picker 和 Menu 之间选择:选项少且平面的用 Menu,选项有层级或需要多列联动的用 Picker。

iOS HIG 有一条明确说明的设计原则:Pop-up Button 的标题始终显示当前选中项的内容,不使用固定标题。这和 Pull-down Button(下拉按钮)不同。Pull-down Button 是用来触发一组操作命令的(比如"分享到…"展开后列出分享渠道),它的标题是固定的,不随选择变化。

设计 iOS 端的下拉选择器时,如果需求是"从一组互斥选项中选一个",用 Pop-up Button 或 Picker;如果需求是"展示一组可执行的动作",用 Pull-down Button。两者的外观相似但语义完全不同,混用会让用户感到困惑。

Android 端的做法不同。MD3 提供了一个 Exposed Dropdown Menu 组件来实现下拉选择功能。这个组件建立在文本框(Text Field)的基础之上。触发区域的外观就是一个文本框,右侧有一个下拉箭头图标,点击后在文本框下方展开选项列表。

MD3 的 Exposed Dropdown Menu 有两种视觉变体,和文本框一样分为 Filled(填充式)和 Outlined(描边式)。Filled 变体的触发区域有浅色背景填充和底部边框线,视觉重量较重,适合需要突出显示的表单场景;

Outlined 变体的触发区域只有一圈描边,没有背景填充,视觉更轻,适合表单字段密集的页面,减少视觉噪音。

触发区域的构成包括四个部分:容器(Container)、标签文字(Label)、选中值文字(Selection text)和尾部的下拉箭头图标(Trailing icon)。标签文字在未选择时显示在容器内部充当引导,用户点击后,标签文字上浮缩小到容器顶部边缘,腾出空间显示选中的内容。如果标签直接消失、选中值直接出现,用户不容易意识到这是两层不同的信息。

标签上浮的动画让这个替换过程可见,用户能明确感知到标签还在、只是退到了容器顶部。这也是 MD3 文本框家族的统一行为,下拉选择器继承了同样的动画。

MD3 的选项列表在视觉上是一个带圆角和轻微阴影的浮动卡片,紧贴触发区域下方展开。每个选项项的高度为 48dp,这种设计保证了移动端的触控友好性。选项项支持前置图标和尾部文字,也支持分隔线分组。

MD3 的 Exposed Dropdown Menu 支持用户在触发区域直接输入文字进行过滤,因为它本质上是一个文本框。用户既可以点击下拉箭头展开完整列表,也可以直接在触发区域打字,列表自动过滤显示匹配项。这让 MD3 的下拉选择器具备了搜索能力,不需要额外在列表顶部添加搜索框。但设计时需要明确:如果这个下拉选择器不需要搜索功能(比如只有五六个选项),触发区域的文本输入能力应该被禁用,只保留点击展开列表的行为,避免用户误以为可以手动输入一个不在选项列表里的选项值。


六、常见误区

选项少于五个还用下拉选择器。 性别选择只有男、女、其他三个选项,放进下拉选择器意味着用户得点击一次才能看到所有选项,再点击一次做出选择。这种两次点击完成的事情,如果用三个单选按钮平铺只需要一次点击。

选项少于五个时,单选按钮可以让用户一眼看到所有选择,不需要先展开再浏览,决策速度会更快。

用占位文本替代标签。 触发区域里写着"请选择国家",上方没有"国家"标签。用户选了"中国"之后,"请选择国家"消失,取而代之的是"中国"二字。这时如果用户回头检查表单,看到的只是一个写着"中国"的输入框,不知道这个字段问的是国籍、出生国还是收货地址。标签必须始终可见,独立于触发区域之外,不能被选中值覆盖。

长列表没有搜索能力。 200 个国家的列表,用户要找"新西兰"得从 A 开头的国家一直往下翻。即使列表按字母排序,用户还得先在脑中把"新西兰"转换成"New Zealand"(如果列表是英文的话),再定位到 N 开头的区域。超过 40 个选项的下拉列表,必须提供搜索过滤能力,让用户输入关键字直接定位。

选项文字被截断但没有补救措施。 触发区域宽度不够,选中项显示为"中华人民共和国澳…",用户无法确认完整内容。选项列表里也是同样的问题,过长的选项文字被截断后,用户无法区分相似的选项——"California, United Sta…"和"California, United Sta…"看起来一模一样,实际上一个是 California, United States,另一个是 California, United States (billing address)。解决办法有两个:加宽触发区域和列表宽度以容纳最长选项,或者在截断处显示省略号并提供悬停 tooltip 展示完整文字。

移动端使用网页自定义下拉替代原生控件。 在手机上用一个从触发区域下方弹出的小面板来展示选项列表,这是直接从桌面端搬过来的交互方式。小面板在手机屏幕上宽度受限、触控目标小、容易被键盘或其他元素遮挡。iOS 和 Android 各自有针对移动场景优化过的原生选择控件(iOS 的 Picker/Menu、Android 的底部列表对话框),这些原生控件的触控面积、滚动手感、和系统整体的交互一致性都经过了平台优化。在移动端应该优先使用原生控件,只有在原生控件确实无法满足设计需求(比如需要选项带图标和描述文字)时,才考虑自定义实现。

展开的列表遮挡了用户需要参考的信息。 用户在填写收货地址表单时,下拉选择器展开的选项列表覆盖住了上方已经填好的省份信息,而用户需要看到省份才能确认该选哪个城市。如果列表展开后遮挡的区域包含和当前选择有关联的信息,用户就不得不在"看列表"和"看参考信息"之间反复切换,操作负担随之增加。设计时需要检查列表展开后会遮挡哪些区域,如果遮挡的内容和当前选择相关,考虑调整下拉选择器的位置布局,或改用不会遮挡内容的选择方式(比如内联的单选按钮组)。

没有处理"无选项匹配"的空状态。 可搜索下拉中,用户输入了一个搜索关键字但没有任何选项匹配。如果列表区域直接变成空白,用户不知道是搜索在加载、是没找到结果、还是控件出了故障。空状态下需要显示明确的提示文字,比如"没有匹配的选项",让用户知道搜索生效了、只是确实没有结果,可以修改关键字重新搜索。

下拉列表没有键盘操作支持。 用户用 Tab 键跳到下拉选择器后,按回车键没有反应,必须切换到鼠标点击才能展开列表。表单场景里用户期望全程用键盘完成填写,任何一个控件需要切换到鼠标都会打断操作节奏。下拉选择器需要支持完整的键盘交互:Tab 聚焦、回车/空格展开、箭头键导航、回车选中、Esc 关闭。

0 人收藏了本文