viewport meta 标签必须完整包含 width=device-width、initial-scale=1、maximum-scale=1、minimum-scale=1;touch-action 应按场景设为 pan-y 或 none;rem/vw 布局需在 head 内尽早动态设置根字号。

viewport meta 标签必须写全,不能只设 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 CSS 属性决定手势是否被浏览器接管
默认情况下,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()配合判断
click 延迟与 passive 事件监听器的取舍
移动端浏览器为区分单击和双击,对 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 布局中 font-size 的动态重置时机很关键
用 rem 或 vw 实现等比缩放时,常见错误是在 DOM 加载后才计算根字号,导致首屏闪动或字体错位。
立即学习“前端免费学习笔记(深入)”;
- 应在
内联一段 JS,在document.documentElement可访问后立即执行,而非等DOMContentLoaded - 监听
resize不够——iOS Safari 横竖屏切换时可能不触发,需同时监听orientationchange - 使用
vw直接布局时,注意100vw包含滚动条宽度,实际可视宽度可能略小;可用100dvw(safari 16.4+ / chrome 110+)替代,但兼容性仍有限 - 不要在 CSS 中写死
html { font-size: 16px },它会覆盖 JS 动态设置的值
视口初始设置和触摸事件接管逻辑,往往在首屏渲染完成前就已起效;很多问题不是代码没写,而是执行时机不对或层级覆盖了。











