📱 安全区域适配(刘海屏 / 底部指示条)

iPhone X 及之后的全面屏机型有刘海、底部 Home 指示条等,需要使用 safe-area-inset 环境变量进行适配。

关键 CSS 环境变量

变量含义典型值(iPhone X)
safe-area-inset-top顶部安全距离44px
safe-area-inset-bottom底部安全距离34px
safe-area-inset-left左侧安全距离0px
safe-area-inset-right右侧安全距离0px

完整适配方案

/* ===== 安全区域全局适配 ===== */

/* ① Viewport 必须添加 viewport-fit=cover */
/* <meta name="viewport" content="..., viewport-fit=cover"> */

/* ② 使用 constant() 和 env() 双写兼容 */
:root {
  --safe-top: env(safe-area-inset-top, constant(safe-area-inset-top));
  --safe-bottom: env(safe-area-inset-bottom, constant(safe-area-inset-bottom));
}

/* ③ 顶部导航栏留出刘海空间 */
.header {
  padding-top: var(--safe-top);
  /* 背景色延伸到安全区域 */
  background: #fff;
}

/* ④ 底部固定栏留出 Home 指示条空间 */
.tab-bar {
  padding-bottom: var(--safe-bottom);
}

/* ⑤ 全屏背景延伸 */
body {
  padding-top: var(--safe-top);
  padding-bottom: var(--safe-bottom);
}

JS 获取安全区域值

// ===== JS 读取安全区域值 =====
function getSafeAreaInsets() {
  const style = getComputedStyle(document.documentElement);
  return {
    top: parseInt(style.getPropertyValue('env(safe-area-inset-top)')) || 0,
    bottom: parseInt(style.getPropertyValue('env(safe-area-inset-bottom)')) || 0,
    left: parseInt(style.getPropertyValue('env(safe-area-inset-left)')) || 0,
    right: parseInt(style.getPropertyValue('env(safe-area-inset-right)')) || 0,
  };
}

// 判断是否是全面屏(有刘海)
const insets = getSafeAreaInsets();
const isNotchScreen = insets.top > 20 || insets.bottom > 20;
console.log('安全区域:', insets, '全面屏:', isNotchScreen);