H5与React-Native android与ios 设置安全区域

一、safe-area-inset-* 是什么时候出现的?

  • 年份2017 年

  • 系统iOS 11

  • 背景:iPhone X 发布(第一次有刘海 + 手势条)

👉 Apple 为了适配全面屏,引入了 Safe Area 概念


二、env() vs constant() 的区别(很关键)

1️⃣ 旧写法:constant()

  • iOS 11.0 ~ 11.2

  • Safari 早期实现

 
constant(safe-area-inset-bottom)

2️⃣ 新写法:env()(现在标准)

  • iOS 11.2+

  • W3C 标准写法

 
env(safe-area-inset-bottom)

三、哪些 iPhone 需要考虑「安全边界」?(重点)

✅ 需要 Safe Area 的机型(全面屏)

只要没有实体 Home 键,全部都要

1️⃣ 刘海屏(Notch)

  • iPhone X

  • iPhone XR

  • iPhone XS / XS Max

  • iPhone 11 / 11 Pro / 11 Pro Max

  • iPhone 12 / 12 Pro / 12 Pro Max / 12 mini

  • iPhone 13 / 13 Pro / 13 Pro Max / 13 mini

2️⃣ 灵动岛(Dynamic Island)

  • iPhone 14 Pro / Pro Max

  • iPhone 15 全系

  • iPhone 16 全系(如果你在适配新机)

📌 结论:
👉 X 及之后的全面屏机型,全部要做 Safe Area 适配


❌ 不太需要 Safe Area 的机型(有 Home 键)

这些机型屏幕是规则矩形:

  • iPhone 6 / 6s

  • iPhone 7 / 8

  • iPhone SE(一代 / 二代 / 三代)

⚠️ 但注意:
即使这些机型,状态栏高度、系统 UI 仍然存在,只是问题没那么明显。


四、H5 Android 需要处理安全区吗?(重点)

👉 99% 的 H5:不需要

原因:

  • Android 状态栏 不覆盖网页内容

  • 底部手势条 不侵占 viewport

  • WebView 已自动避让

⚠️ 少数例外

  • 沉浸式全屏 WebView

  • 自定义状态栏高度

  • 刘海屏强制铺满

👉 这些通常由 App 端处理,而不是 H5


五、React-Native iOS / Android 行为差异

平台Safe Area 来源
iOS 刘海 / 灵动岛 / Home 指示条
Android 状态栏 / 手势导航

👉 react-native-safe-area-context 统一帮你算好了


一、H5(浏览器 / WebView)安全区域设置

1️⃣ 必须加的 meta(iOS 必需)

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

没有这个:
👉 iOS 的 safe-area 全部为 0


2️⃣ 统一 CSS(iOS 生效,Android 自动为 0)

 
:root { --safe-top: env(safe-area-inset-top); --safe-bottom: env(safe-area-inset-bottom); --safe-left: env(safe-area-inset-left); --safe-right: env(safe-area-inset-right); }

(可选:兼容 iOS 11.0–11.2)

 
:root { --safe-top: constant(safe-area-inset-top); --safe-bottom: constant(safe-area-inset-bottom); }

3️⃣ 常见 H5 场景

底部按钮 / fixed 底栏

 
.footer { padding-bottom: calc(12px + var(--safe-bottom)); }

顶部导航

 
.header { padding-top: calc(12px + var(--safe-top)); }

全屏页面

 
.page { padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left); }

📌 结论:

  • iOS 刘海 / 灵动岛 → 有值

  • Android / 老 iPhone → 0,不影响布局


二、React Native(原生)安全区域设置

⚠️ RN 不用 CSS,不用 env()


1️⃣ 安装官方库

 
npm install react-native-safe-area-context

2️⃣ 根节点包一层 Provider

 
import { SafeAreaProvider } from 'react-native-safe-area-context'; export default function App() { return ( <SafeAreaProvider> <Main /> </SafeAreaProvider> ); }

3️⃣ RN 三种常用写法

✅ 整页安全区

 
import { SafeAreaView } from 'react-native-safe-area-context'; <SafeAreaView style={{ flex: 1 }}> {/* 页面内容 */} </SafeAreaView>

✅ 底部按钮(最常见)

 
import { useSafeAreaInsets } from 'react-native-safe-area-context'; const insets = useSafeAreaInsets(); <View style={{ paddingBottom: insets.bottom + 12 }}> <Button title="提交" /> </View>

✅ fixed / absolute 元素

 
<View style={{ position: 'absolute', bottom: 0, left: 0, right: 0, paddingBottom: insets.bottom, }} > <Footer /> </View>

📌 iOS / Android 差异:

  • iOS:刘海 / 灵动岛 / Home 条

  • Android:状态栏 / 手势导航

  • 库已统一处理


三、H5 & RN 安全区域对照表(速查)

场景H5React Native
技术方式 CSS env() 原生 API
顶部安全区 env(safe-area-inset-top) insets.top
底部安全区 env(safe-area-inset-bottom) insets.bottom
Android 处理 自动为 0 自动计算
推荐方案 CSS 变量 safe-area-context

四、最容易踩的 3 个坑(重点)

❌ 1. H5 + RN WebView 双重 padding

👉 只能一边处理安全区

❌ 2. RN 用了 react-native 自带 SafeAreaView

👉 Android 行为不一致

❌ 3. H5 忘了 viewport-fit=cover

👉 iOS 全失效


五、一句话总结

H5 用 CSS Safe Area(只为 iOS)
RN 用原生 Safe Area(iOS / Android 通吃)

posted @ 2025-12-17 14:07  jerry-mengjie  阅读(36)  评论(0)    收藏  举报