iOS Safari 在表单元素聚焦时强制放大视口,因其可访问性逻辑要求最终渲染 font-size ≥16px;需同时确保 viewport 设置正确、元素显式设 font-size: 16px !important 且含 :focus 规则,并验证 computed 值。

input:focus 时页面放大,根本不是缩放 bug,而是 Safari 的可访问性逻辑
iOS Safari 在 input、textarea、select 或带 contenteditable 的元素聚焦时,会硬编码检查其**最终渲染的 font-size**。只要小于 16px(注意:是计算后值,不是你写的声明),就强制放大整个视口——这不是 bug,是设计行为。
所以别再只改 font-size: 16px 就以为完事。常见掉坑点:
- 根元素
html { font-size: 12px },再写1.333rem→ 实际算出来15.996px,Safari 四舍五入判为< 16px - 父容器用了
font-size: 0.875em,子input继承后直接掉到14px - 用了
clamp(14px, 4vw, 16px),小屏下4vw在320px宽度上仅12.8px - UI 库(如
<van-field>)把font-size写进内联style,你的 CSS 被覆盖
必须同时生效的三要素:viewport + 字号 + 选择器范围
缺一不可,且顺序和写法都有讲究:
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0">必须放在<head>最顶部,不能 JS 动态注入,也不能被 Cordova/Ionic 插件覆盖 -
input、textarea、select、[contenteditable]都要显式设font-size: 16px !important,不能只写input - 必须加
:focus伪类规则,否则某些框架在 focus 时动态加 class 可能导致字号回落 -
-webkit-text-size-adjust: 100%要和font-size同级写在表单元素上,不是写在body上——它只在字号 ≥16px 时起作用,单独写无效
Vue/React 项目里,CSS 很可能没生效
框架组件常在 mounted 阶段动态注入样式,或用 CSS-in-JS 生成高优先级 class,把你写的规则盖掉:
立即学习“前端免费学习笔记(深入)”;
-
<van-field>或<Input>组件内部用内联style设置了font-size,得用更强选择器覆盖,例如:input:not([type="hidden"]) !important - 查「Computed」面板确认最终
font-size值,别信源码里写的那行 CSS - 避免用
rem/em,优先用px或clamp(16px, 4vw, 18px)(确保下限真 ≥16px) - 如果用了 Ant Design Mobile/Vant,直接在组件上加
style="font-size: 16px !important"是最快验证方式
Android 和其他浏览器不用刻意适配
这个行为是 iOS Safari 独有。Chrome for Android、Firefox、Edge Mobile 都不触发该逻辑。但要注意:
-
vh单位在 iOS Safari 中不稳定(地址栏收放导致视口高度跳变),若页面整体高度用了100vh,可能伴随白边或滚动异常,建议改用100% -
user-scalable=no在 iOS 10.3+ 已被忽略,依赖它等于没设;真正起效的是minimum-scale=1.0和maximum-scale=1.0的组合 - 多个
<meta name="viewport">标签时,只有第一个生效——检查构建产物里有没有重复插入


















