← 全部文章

viewport meta 标签详解:该怎么写,为什么

移动端 viewport meta 标签的作用、每个页面都需要的那一行代码、应避免的取值,以及 viewport-fit 和 interactive-widget 等新选项。

viewport meta 标签告诉移动端浏览器,页面的布局区域要多宽、初始缩放比例是多少。几乎每个网站都应该在 <head> 中原样使用这一行:

<meta name="viewport" content="width=device-width, initial-scale=1">

没有它,手机会认为页面是桌面端设计,按大约 980 px 的宽度布局,再缩小到适合屏幕。你的响应式 CSS 根本没有机会生效。

没有 viewport meta 标签会怎样

最早的智能手机出现时,大多数网站都是为桌面屏幕设计的。为了能显示这些网站,移动端浏览器假装自己有一个桌面尺寸的“布局视口”(iOS Safari 和安卓 Chrome 中为 980 px),然后缩小页面,让整页都能放进屏幕。用户再用双指放大来阅读。

对于任何没有 viewport 标签的页面,这个默认行为至今仍然有效。在屏幕宽 390 px 的手机上,这样的页面会:

  • 向 CSS 和 JavaScript 报告约 980 px 的视口宽度
  • 永远不会匹配 (max-width: 600px) 这样的媒体查询
  • 文字只显示为预期大小的 40% 左右

如果你的网站在手机上看起来像一个缩小的桌面页面,首先检查这个标签。这是网站在手机上显示错乱的原因中最常见的一种。

每个取值的含义

取值 含义 是否推荐
width=device-width 把布局视口设为设备的 CSS 像素宽度(例如很多 iPhone 为 390) 推荐
initial-scale=1 初始缩放为 100%,1 个 CSS 像素对应 1 个设备无关像素 推荐
minimum-scale 允许的最小缩放 很少需要
maximum-scale 允许的最大缩放 避免小于 5 的值
user-scalable=no 禁用双指缩放 避免
width=1024(固定数值) 强制使用固定的布局宽度 响应式网站应避免
viewport-fit=cover 让页面延伸到刘海和圆角下方 仅在配合安全区域内边距时使用
interactive-widget 控制屏幕键盘如何调整页面大小 可选

为什么不应该禁用缩放

user-scalable=no 和 maximum-scale=1 会阻止用户放大页面。这会让低视力用户难以甚至无法阅读,也违反了 WCAG 关于文字可放大到 200% 的要求。Lighthouse 的无障碍审核会标记这个问题。

开发者加这些值,常常是为了阻止 iOS Safari 在表单字段上自动放大。正确的做法是让输入框的字号至少为 16 px:

input, select, textarea { font-size: 1rem; }

而且,较新的 iOS Safari 在双指缩放上本来就会忽略 user-scalable=no,所以这个标签主要是在其他浏览器上造成危害。

viewport-fit=cover 与安全区域

在有刘海、灵动岛或圆角的手机上,浏览器默认把页面限制在一个安全的矩形内。viewport-fit=cover 让页面占满整个屏幕,全出血设计可能需要这样做。这时你必须自己让内容避开刘海和主屏幕指示条:

<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
.site-header {
  padding-left: max(1rem, env(safe-area-inset-left));
  padding-right: max(1rem, env(safe-area-inset-right));
}
.bottom-bar { padding-bottom: env(safe-area-inset-bottom); }

请在横屏下测试,此时刘海位于侧边。

interactive-widget 与屏幕键盘

键盘弹出时,浏览器要么只缩小视觉视口(Chrome 和 Safari 的默认行为),要么调整整个布局的大小。较新的 interactive-widget 取值可以让你选择:

  • resizes-visual:默认值;布局大小不变,键盘遮住其中一部分
  • resizes-content:布局视口缩小,因此使用 100dvh 的元素和固定页脚会移到键盘上方
  • overlays-content:不调整任何大小;需要你用 VirtualKeyboard API 自行处理

各浏览器的支持情况不同(基于 Chromium 的浏览器支持;依赖它之前请先确认当前的支持情况),所以无论如何都要在真机上测试表单。

可以删除的过时取值

  • shrink-to-fit=no 是针对 iOS 9 的权宜之计,现在已经没有作用。
  • target-densitydpi 是旧版安卓的取值,现已被忽略。
  • <meta name="HandheldFriendly"> 和 <meta name="MobileOptimized"> 是功能机时代的产物。

如何检查你的 viewport 标签

  1. 查看页面源代码,搜索 name="viewport"。应该恰好有一个。
  2. 在移动模式下运行 Lighthouse 审核(操作方法),它会报告缺失或阻止缩放的 viewport 标签。
  3. 用手机视图打开页面。在 DevTools 设备模式中,或在按真实手机尺寸加载页面的 Mobile View Extension 中,没有该标签的页面看起来是缩小的,文字很小。

常见问题

正确的 viewport meta 标签是什么?

<meta name="viewport" content="width=device-width, initial-scale=1">。只有在做全屏布局并处理安全区域时,才添加 viewport-fit=cover。

做响应式设计需要 viewport meta 标签吗?

需要。没有它,移动端浏览器会按大约 980 px 的宽度布局页面,移动端媒体查询永远不会生效。

使用 user-scalable=no 不好吗?

从无障碍角度看不好。它会阻止用户放大文字。表单字段上不想要的自动放大,请改用 16 px 的输入框字号来解决。

用手机视图查看你的下一个网站。

添加扩展,在你正在使用的标签页中直接打开设备预览。