viewport元标签必须设为width=device-width, initial-scale=1.0并置于head最前,否则手机端按桌面宽度渲染导致缩放异常;它与媒体查询协同工作,不可替代;需配合text-size-adjust:100%防文本误缩放。

viewport 元标签写不对,页面在手机上会缩成一团
绝大多数响应式失效,不是 CSS 写得不好,而是 根本没加,或者加了但 content 值写错。iOS Safari 和 Android Chrome 都依赖这个标签来决定页面初始缩放行为。不设或设错,浏览器就会按桌面宽度(通常是 980px 或 1280px)渲染,再整体缩小显示——文字小到看不清,点击区域错位,max-width: 100% 也救不回来。
- 必须放在
内,且越靠前越好(不能等 JS 加载完再动态插入) - 最常用、最稳妥的值是:
width=device-width, initial-scale=1.0 - 不要写
user-scalable=no—— 屏幕阅读器、视力障碍用户需要缩放,iOS 13+ 甚至会忽略该属性 - 避免用固定数值如
width=375,不同设备device-width不同(iPhone 14 Pro 是 390,Pixel 7 是 412)
initial-scale=1.0 不等于“禁止缩放”
initial-scale=1.0 只控制页面加载时的初始缩放比例,不影响用户后续的手势缩放。如果你看到“页面一打开就放大/缩小”,大概率是 initial-scale 被设成了非 1 的值(比如 0.5 或 2.0),或是同时写了 maximum-scale 等限制项。
- 想允许用户自由缩放:只保留
width=device-width, initial-scale=1.0 - 想禁用双指缩放(不推荐):加上
user-scalable=no, maximum-scale=1.0, minimum-scale=1.0,但注意这违反 WCAG 可访问性标准 -
minimum-scale和maximum-scale在 iOS 10+ 中已被弱化,部分机型直接无视
viewport 与 CSS 媒体查询不是替代关系
有人以为加了 viewport 就不用写 @media,这是误解。viewport 解决的是“页面按什么宽度渲染”,媒体查询解决的是“在这个宽度下显示什么样式”。两者必须配合:
- 没有 viewport,
@media (max-width: 768px)可能永远不触发(因为浏览器按 980px 渲染) - 有 viewport 但没媒体查询,页面虽能正常缩放,但布局仍是 PC 版,文字挤在一起,按钮太小
- viewport 中的
width=device-width对应 CSS 中的screen.width,不是物理像素,而是 CSS 像素(受 DPR 影响)
高 DPR 设备(如 iPhone)下字体模糊?检查 text-size-adjust
某些安卓浏览器(尤其旧版 Samsung Internet)会在横屏时自动放大文本,导致布局错乱;iOS 则可能因 text-size-adjust 触发意外缩放。这不是 viewport 问题,但常被误认为是。
立即学习“前端免费学习笔记(深入)”;
- 加一行 CSS 阻止非预期文本缩放:
html { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; text-size-adjust: 100%; } - 注意:设为
none会彻底禁用用户缩放,不可取;100%是安全平衡点 - 这个属性不影响 viewport 缩放逻辑,只约束浏览器对文本的独立调整行为
device-width)、定好初始比例(1.0)、不加多余限制。其余都是锦上添花,甚至画蛇添足。真正难的不是写对这一行,而是确保它出现在所有页面的 里——CMS 模板、SSR 框架、微前端子应用,都容易漏掉或覆盖。











