根本原因是iOS Safari和Android WebView对表单控件有私有渲染逻辑:iOS强制拉高font-size<16px的input并重算行高,Android忽略line-height按字体度量撑高;需统一设font-size≥16px、line-height写死、禁用height、加-webkit-appearance:none,并用background-image替代原生select箭头,:focus用box-shadow模拟,禁用态显式重写-webkit-text-fill-color。

移动端 input/textarea/select 高度不一致的根本原因
不是你写错了 CSS,而是 iOS Safari 和 Android WebView 对表单控件有两套“私有渲染逻辑”:iOS 会强制将 font-size 小于 16px 的 input 拉高并重算行高,Android 则可能忽略 line-height 直接按字体度量撑开高度。结果就是同一段代码,在 Chrome for Android 看着正常,在 Safari 里输入框被压扁、光标偏上、placeholder 贴顶。
- 必须显式设置
font-size: 1rem(推荐 ≥16px),不能留空或设为0.875rem -
line-height必须写死,比如line-height: 1.5或line-height: normal,别用line-height: 1—— 它在 iOS 下会被无视 - 禁用
height固定值,靠padding+font-size+line-height组合控制高度,更稳定 - 所有控件加
-webkit-appearance: none,否则 iOS 会叠加内阴影和圆角,干扰你的样式
select 下拉箭头在 Safari/Chrome/Firefox 中位置错乱
原生 select 的下拉图标不是标准 CSS 元素,各浏览器画在不同位置:Safari 画在 border 内侧右端,Chrome 画在 padding 区右侧,Firefox 根本不支持伪元素覆盖。直接设 padding-right 会导致 Safari 文字被箭头遮挡,Chrome 又留白太多。
- 统一用
background-image替代原生箭头,SVG Base64 最稳妥(避免请求) - 去掉
padding-right,改用padding-left+text-indent微调文字起始位置 - 必须配
appearance: none,否则背景图会被原生箭头盖住 - 给
select加vertical-align: middle,解决与相邻标签的基线对齐问题
:focus 和 :focus-visible 在移动端的视觉冲突
在 iOS Safari 和部分安卓 WebView 中,点击输入框触发 :focus 时,原生蓝色外框(outline)不会自动消失,反而和你写的 border-color 叠加,看起来边框变粗、圆角被截断。更麻烦的是,:focus-visible 在触屏设备上基本不触发,纯靠键盘操作才生效。
- 别用
outline: none—— 这会让键盘用户失去焦点指示 - 用
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.25)模拟 focus 状态,它尊重border-radius - 对触屏设备单独加媒体查询:
@media (hover: none) and (pointer: coarse),里面只启用:focus规则,屏蔽:focus-visible - 确保
outline-offset设为2px,避免 shadow 和 border 粘连
禁用状态下文字颜色不统一(尤其 Element Plus 类库)
框架如 Element Plus 对 el-input、el-select、el-textarea 的禁用态处理不一致:el-input 默认用了 -webkit-text-fill-color 控制灰度文字,但 el-select 和 el-textarea 没有,导致同个页面里三者文字深浅不同,哪怕你写了相同的 color 值也无效。
立即学习“前端免费学习笔记(深入)”;
- 必须显式重写所有禁用控件的
-webkit-text-fill-color,例如:-webkit-text-fill-color: #999 - 配合
color和opacity(慎用,影响可访问性)做兜底 - 如果用 Vue 深度选择器(如
:deep()),要分别命中.el-input__inner、.el-select__input、.el-textarea__inner三层 - 注意
disabled属性本身会触发 UA 样式,所以类名 + 属性组合选择器(如.form-control:disabled)比纯类名更可靠
appearance 的部分支持、以及各浏览器对 :user-invalid 的触发时机差异。这些地方没显式覆盖,光靠类名或框架封装,很容易在某个机型上突然崩掉。


















