viewport meta 标签必须完整包含 width=device-width、initial-scale=1、maximum-scale=1、minimum-scale=1;touch-action 应按场景设为 pan-y 或 none;rem/vw 布局需在 head 内尽早动态设置根字号。
width移动端页面不加或错配 ,会导致布局在 iOS 和 Android 上表现不一致:文字过小、横向滚动、缩放失效。常见错误是只写 width=device-width,漏掉关键参数。
initial-scale=1 必须显式声明,否则 Safari 在横屏切换时可能自动缩放user-scalable=no 要慎用——iOS 10+ 对其支持不稳定,且 WCAG 可访问性不达标;如需禁用缩放,优先用 maximum-scale=1, minimum-scale=1
shrink-to-fit=no 是 Safari 特有旧参数,仅在 iOS 9–11 生效,现代项目可省略默认情况下,touch-action: auto 允许浏览器响应双指缩放、长按选中、滑动滚动等行为,但会干扰自定义拖拽或手势识别(比如轮播图卡顿、Canvas 手势失灵)。
touch-action: pan-y,保留垂直滚动,禁用水平拖拽冲突touch-action: none,彻底交出手势控制权给 JS 或根元素上全局设 touch-action: none,否则页面无法滚动touch-action 在 iOS Safari 13.4+ 才完整支持 pan-x/pan-y,旧版本 fallback 方案需靠 preventDefault() 配合判断移动端浏览器为区分单击和双击,对 touchstart 后的 click 强制增加约 300ms 延迟。虽然 fastclick 库曾流行,但现在更推荐原生方案。
touchend 替代 click 并调用 preventDefault(),但要注意:若该元素本身需要滚动穿透(如模态框遮罩层),preventDefault() 会阻断背景滚动touchstart 或 touchmove 时,务必加 { passive: false } 显式声明——Chrome / Safari 默认设为 true,导致 preventDefault() 失效并抛警告click 延迟在 Chrome for Android 和 Safari 中已默认关闭(当 viewport 包含 width=device-width 且无 user-scalable=no),但 iOS 仍部分保留,不可完全依赖用 rem 或 vw 实现等比缩放时,常见错误是在 DOM 加载后才计算根字号,导致首屏闪动或字体错位。
内联一段 JS,在 document.documentElement 可访问后立即执行,而非等 DOMContentLoaded
resize 不够——iOS Safari 横竖屏切换时可能不触发,需同时监听 orientationchange
vw 直接布局时,注意 100vw 包含滚动条宽度,实际可视宽度可能略小;可用 100dvw(safari 16.4+ / chrome 110+)替代,但兼容性仍有限html { font-size: 16px },它会覆盖 JS 动态设置的值视口初始设置和触摸事件接管逻辑,往往在首屏渲染完成前就已起效;很多问题不是代码没写,而是执行时机不对或层级覆盖了。