原生 <select> 无法用 CSS 控制下拉弹出层滚动,因其选项列表由系统/浏览器 UI 层独立绘制,不参与 DOM 流;唯一纯 HTML/CSS 方案是用 size 属性转为多行常驻列表并设置 height 和 overflow-y: auto。

原生 <select> 无法用 CSS 控制下拉弹出层滚动
直接给 <select> 加 overflow-y: auto 或 max-height 完全无效。因为浏览器点击后弹出的选项列表,是操作系统或浏览器 UI 层独立绘制的,不参与 DOM 流,也不响应常规 CSS。你在开发者工具里看到的 <select> 只是个触发器,真正的菜单不在 HTML 树中。
用 size 属性转为多行常驻列表再加滚动
这是唯一能用纯 HTML/CSS 实现“可滚动选项区”的合法方式:把下拉变成固定高度的多行列表,此时它就是一个普通块级元素,height 和 overflow-y: auto 才起作用。
-
size值设为大于 1 的整数(如size="6"),<select>就不再弹出,而是以列表形式常驻显示 - 必须显式设置
height(比如height: 150px),否则overflow-y不生效 - 建议搭配
box-sizing: border-box,避免 padding/border 导致内容被截断 - 该方案语义仍是单选,但 UX 更接近“带滚动的列表框”,不是传统下拉箭头交互
示例:
<select size="6" style="height: 150px; overflow-y: auto; box-sizing: border-box;"> <option>选项一</option> <option>选项二</option> <!-- 更多选项... --> </select>
需要真正下拉 + 滚动?只能用 JS 自定义
如果必须保留“点击展开、带箭头、键盘可导航、支持搜索”等体验,原生 <select> 无解。得用 JS 完全重写 UI:
立即学习“前端免费学习笔记(深入)”;
- 隐藏原生
<select>(opacity: 0; position: absolute;) - 用
<div class="custom-select">模拟按钮,点击时显示<ul class="dropdown-list"> - 在
<ul>上设max-height: 200px; overflow-y: auto;,滚动完全可控 - 需手动处理焦点、键盘(
ArrowDown/Enter)、屏幕阅读器aria-*属性
注意:别试图用 -webkit-appearance: none + position: relative 强行干预原生弹出层——不同浏览器表现差异极大,iOS 和 macOS 下基本不可靠。
移动端下拉刷新和下拉菜单别混淆
标题里的“下拉”容易引发歧义。如果是想实现类似微信朋友圈那种“手指下拉加载新内容”的效果,那属于 pull-to-refresh 场景,和表单 <select> 完全无关。它依赖 touchstart/move/end 监听、scrollTop === 0 判断、transform: translateY() 动画,且必须作用于一个明确的 overflow-y: auto 容器,不能绑在 body 上。
真正难的从来不是加滚动条,而是让滚动行为符合用户预期:什么时候该出现、滚动是否平滑、键盘能否操作、屏幕阅读器能否识别——这些都得在自定义方案里逐项补全,漏掉任何一点,就只是个“能滚的假下拉”。



















