ios safari 输入框聚焦时页面放大是可访问性机制,非bug;核心解法是确保input、textarea、select、[contenteditable]元素及其:focus态的computed font-size严格≥16px,并配合-webkit-text-size-adjust: 100%和viewport中maximum-scale=1.0、minimum-scale=1.0、user-scalable=no组合使用。

iOS Safari 在 input、textarea、select 或带 contenteditable 属性的元素聚焦时自动放大页面,不是 bug,而是它硬编码的可访问性逻辑:只要这些元素「最终渲染的 font-size 小于 16px」,就强制放大整个视口。CSS 能做的不是“阻止缩放”,而是让 Safari “觉得没必要缩放”——核心就是守住 16px 这条线。
为什么写了 font-size: 16px 还会放大?
因为 Safari 看的是 computed 值,不是你写的声明值。常见失效场景:
-
html { font-size: 14px; }+input { font-size: 1.143rem; }→ 实际 ≈ 15.99px(浮点误差触发放大) - 父容器设了
font-size: 0.875em,子input未重置,继承后掉到 14px 以下 - 用了
clamp(14px, 4vw, 18px),小屏下 4vw 在 320px 宽度上仅 12.8px - UI 库(如 Vant、Ant Design Mobile)动态注入内联样式,把你写的
font-size覆盖了
必须覆盖哪些元素和状态?
只写 input 和 textarea 不够。iOS 同样检查:
-
select下拉框 - 所有带
contenteditable属性的容器(哪怕只是div[contenteditable]) - 富文本编辑器根节点(Quill、Tiptap、Vue 的
v-model绑定的div[contenteditable]) - 必须同时写普通态和
:focus态,防止某些框架在聚焦时动态加 class 导致字号回落
推荐兜底写法:
input, textarea, select, [contenteditable] {
font-size: 16px !important;
}
input:focus, textarea:focus, select:focus, [contenteditable]:focus {
font-size: 16px !important;
}
-webkit-text-size-adjust: 100% 怎么用才有效?
这个属性不是“禁用缩放”,而是告诉 Safari:别对文本做二次字号重计算。但它只在 font-size ≥ 16px 时起效:
- 不能写在
body或html上——会导致正文小字也变难读 - 必须和
font-size: 16px同级写在表单元素上,例如:input { font-size: 16px !important; -webkit-text-size-adjust: 100%; } - 不要用
none:iOS 10+ 已废弃,部分版本反而失效
viewport meta 标签怎么配才不白写?
user-scalable=no 单独存在会被 Safari 忽略。真正起效的是组合:
-
maximum-scale=1.0和minimum-scale=1.0必须同时出现 -
user-scalable=no的值必须是字符串"no"(不能是false或空) - 多个
meta name="viewport"标签时,只有第一个生效;某些框架(如 Ionic)会动态重写它
最稳写法(放在 最顶部):
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
注意:initial-scale=1.0 和 minimum-scale=1.0 不是冗余项,后者是防 fallback 的关键。
真正容易被忽略的是:动态内容和框架组件可能在运行时覆盖你的 CSS;测试时务必用 Safari 开发者工具查「Computed」面板里的 font-size 值,而不是只信源码声明。16px 是临界整数,15.99px 就算差 0.01 也会放大。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











