Uniapp处理安全区域

Gary Chen
Uniapp处理安全区域

Uniapp 中使用 safe-area-inset-top 和 safe-area-inset-bottom 处理安全区域

在 Uniapp 中处理 iPhone X 及以上机型的刘海屏和底部安全区域,可以使用 safe-area-inset-topsafe-area-inset-bottom 这两个 CSS 变量。这些变量会自动适配不同设备的屏幕安全区域。

基本使用方法

1. 在样式文件中使用

/* 顶部安全区域 */
.safe-area-top {
  padding-top: var(--status-bar-height); /* 状态栏高度 */
  padding-top: constant(safe-area-inset-top); /* iOS 11.0 */
  padding-top: env(safe-area-inset-top); /* iOS 11.2+ */
}

/* 底部安全区域 */
.safe-area-bottom {
  padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */
  padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2+ */
}

2. 在页面中应用

<template>
  <view class="container">
    <!-- 顶部安全区域 -->
    <view class="header safe-area-top">
      头部内容
    </view>
    
    <!-- 中间内容 -->
    <scroll-view class="content" scroll-y>
      页面内容
    </scroll-view>
    
    <!-- 底部安全区域 -->
    <view class="footer safe-area-bottom">
      <input placeholder="输入内容" />
    </view>
  </view>
</template>

完整示例

<template>
  <view class="page-container">
    <!-- 固定头部,考虑安全区域 -->
    <view class="header safe-area-top">
      头部标题
    </view>
    
    <!-- 中间可滚动内容 -->
    <scroll-view class="content" scroll-y>
      <view class="content-inner">
        <!-- 页面内容 -->
        <view v-for="item in 30" :key="item">
          内容行 {{item}}
        </view>
      </view>
    </scroll-view>
    
    <!-- 固定底部,考虑安全区域 -->
    <view class="footer safe-area-bottom">
      <input class="input" placeholder="请输入内容" />
    </view>
  </view>
</template>

<style>
/* 基础样式 */
.page-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

/* 安全区域适配 */
.safe-area-top {
  padding-top: var(--status-bar-height);
  padding-top: constant(safe-area-inset-top);
  padding-top: env(safe-area-inset-top);
}

.safe-area-bottom {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

/* 头部样式 */
.header {
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  background: #007AFF;
  color: white;
  /* 固定高度加上安全区域padding */
  box-sizing: content-box;
}

/* 内容区域 */
.content {
  flex: 1;
  overflow: hidden;
}

.content-inner {
  padding: 20rpx;
}

/* 底部样式 */
.footer {
  background: #f7f7f7;
  padding: 20rpx;
  border-top: 1rpx solid #eee;
  /* 固定高度加上安全区域padding */
  box-sizing: content-box;
}

.input {
  width: 100%;
  height: 80rpx;
  border: 1rpx solid #ddd;
  border-radius: 8rpx;
  padding: 0 20rpx;
  background: white;
}
</style>

注意事项

  1. 兼容性写法

    • 同时使用 constant()env() 是为了兼容不同 iOS 版本
    • constant() 用于 iOS 11.0-11.2
    • env() 用于 iOS 11.2+
  2. box-sizing

    • 当为固定高度的元素添加安全区域 padding 时,通常需要设置 box-sizing: content-box,否则 padding 会被包含在高度内
  3. 微信小程序配置

    • pages.json 中配置 "style": { "navigationStyle": "custom" } 时,需要自行处理顶部安全区域
  4. 非 iOS 设备

    • 在非 iOS 设备上,这些安全区域值通常为 0,所以可以安全使用
  5. H5 端

    • 在 H5 端,这些 CSS 变量可能不会被识别,需要添加 fallback 值:
    .safe-area-top {
      padding-top: 20px; /* 默认值 */
      padding-top: var(--status-bar-height);
      padding-top: constant(safe-area-inset-top);
      padding-top: env(safe-area-inset-top);
    }
    

通过这些方法,你可以确保你的 Uniapp 应用在各种全面屏设备上都能正确显示,避免内容被刘海或底部 Home 条遮挡。