浏览器原理 · 37/51
1. addEventListener 第三个参数 2. addEventListener 与 attachEvent 区别 3. 浏览器兼容性测试与内核 4. 浏览器兼容性问题 5. 浏览器内核与引擎 6. 浏览器图层创建条件 7. 浏览器多进程架构 8. 浏览器渲染机制 9. 浏览器存储方案 10. 浏览器版本检测方法 11. children 与 childNodes 区别 12. 常见浏览器兼容性问题 13. Chrome 页面进程数量 14. 坐标系统对比 15. 多标签页通讯方案 16. 删除 Cookie 17. 自定义事件 18. DOM 事件处理方式演进 19. 元素尺寸属性对比 20. DOM 节点操作 21. DOM 事件机制 22. addEventListener 与 attachEvent 的区别 23. 获取页面所有复选框 24. HTMLCollection 与 NodeList 区别 25. Hybrid 应用开发 26. 强缓存命中机制 27. 浏览器缓存机制 28. 页面编码与资源编码不一致处理 29. jQuery 事件绑定方法对比 30. Input 点击触发的事件顺序 31. JavaScript 浏览器兼容性问题 32. jQuery 多事件绑定实现 33. JSBridge 原理 34. 链接点击后 Hover 失效解决方案 35. 减少重绘和回流的性能优化 36. 移动端 300ms 点击延迟问题 37. 移动端视口配置 38. 移动端点击穿透问题解决 39. 移动端兼容性问题 40. JSBridge 原理与实现 41. 移动端 1px 像素问题解决方案 42. 浏览器渲染流程 43. 页面加载完成事件对比 44. Offset、Scroll、Client 属性对比 45. 同源策略与跨域解决方案 46. Script 标签位置对页面加载的影响 47. Service Worker 与 PWA 48. 存储方案对比:Cookie、Storage、IndexedDB 49. 强缓存默认时间 50. URL 到页面显示的完整过程 51. V8 引擎 JavaScript 执行过程

移动端视口配置

viewport meta 标签的属性与常见配置方案

问题

如何正确配置移动端视口(viewport),让页面在移动设备上正常显示?

解答

基本概念

视口(viewport)是浏览器显示页面内容的区域。移动端有三种视口:

  • 布局视口(layout viewport):页面实际布局的区域,默认宽度通常为 980px
  • 视觉视口(visual viewport):用户当前看到的区域
  • 理想视口(ideal viewport):设备屏幕宽度

viewport meta 标签

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

属性说明

属性说明取值
width视口宽度数值 或 device-width
height视口高度数值 或 device-height
initial-scale初始缩放比例0.0 - 10.0
minimum-scale最小缩放比例0.0 - 10.0
maximum-scale最大缩放比例0.0 - 10.0
user-scalable是否允许用户缩放yes / no
viewport-fit适配刘海屏auto / contain / cover

常见配置方案

<!-- 标准配置:推荐使用 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- 禁止缩放:不推荐,影响无障碍访问 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

<!-- 适配 iPhone X 刘海屏 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

配合 CSS 安全区域

/* 适配刘海屏的安全区域 */
body {
  /* 顶部安全距离 */
  padding-top: env(safe-area-inset-top);
  /* 底部安全距离(Home 指示条) */
  padding-bottom: env(safe-area-inset-bottom);
  /* 左右安全距离(横屏时) */
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* 兼容旧版本 iOS */
@supports (padding: max(0px)) {
  body {
    padding-bottom: max(12px, env(safe-area-inset-bottom));
  }
}

完整示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <!-- 视口配置 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
  <title>移动端页面</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      /* 适配安全区域 */
      padding: env(safe-area-inset-top) 
               env(safe-area-inset-right) 
               env(safe-area-inset-bottom) 
               env(safe-area-inset-left);
    }
    
    .container {
      width: 100%;
      min-height: 100vh;
      background: #f5f5f5;
    }
  </style>
</head>
<body>
  <div class="container">
    <!-- 页面内容 -->
  </div>
</body>
</html>

通过 JS 获取视口信息

// 布局视口宽度
const layoutWidth = document.documentElement.clientWidth;

// 视觉视口宽度(考虑缩放)
const visualWidth = window.innerWidth;

// 设备像素比
const dpr = window.devicePixelRatio;

// 监听视口变化
window.visualViewport?.addEventListener('lypu7', (e) => {
  console.log('视口宽度:', e.target.width);
  console.log('视口高度:', e.target.height);
  console.log('缩放比例:', e.target.scale);
});

关键点

  • width=device-width 让布局视口等于设备宽度,是移动端适配的基础
  • initial-scale=1.0 设置初始缩放为 1,避免页面被自动缩放
  • 不建议禁止用户缩放(user-scalable=no),会影响无障碍访问
  • 刘海屏适配需要 viewport-fit=cover 配合 env(safe-area-inset-*) 使用
  • 视口配置影响 CSS 媒体查询和响应式布局的计算基准