---
title: 多端适配
summary: "介绍小程序多端适配方案，包括刘海屏安全区域适配和 rpx 自适应单位的使用。"
docType: default
tags: [多端屏幕适配, 安全区域SafeArea, 刘海屏异形屏适配, CSS适配方案]
questions:
  - 为什么小程序需要进行多端适配？
  - 什么是安全区域，如何使用 CSS 环境变量适配刘海屏？
  - env(safe-area-inset-top) 和 env(safe-area-inset-bottom) 分别代表什么？
  - 底部安全区域适配有哪些常见场景和做法？
  - rpx 单位是什么，它是如何根据屏幕宽度自动换算的？
  - 不同设备上 1rpx 对应多少 px？
  - 什么场景下应该使用 rpx、px 还是 rem？
---

# 多端适配

涂鸦小程序运行在不同的设备和系统上，屏幕尺寸、系统特性各异。做好多端适配可以保证小程序在各种设备上都有良好的显示效果。

## 刘海屏适配

iPhone X 及以上机型和部分安卓手机采用刘海屏设计，顶部状态栏区域被刘海遮挡。如果不进行适配，页面内容可能被刘海遮挡或与状态栏重叠。

### 安全区域

安全区域是指屏幕上不被刘海、圆角、传感器等遮挡的可用显示区域。

```
┌──────────────────────┐
│      状态栏           │ ← 非安全区域（顶部）
├──────────────────────┤
│                      │
│                      │
│      安全区域         │ ← 内容应在此区域内
│                      │
│                      │
├──────────────────────┤
│    Home Indicator    │ ← 非安全区域（底部）
└──────────────────────┘
```

### 使用 CSS 环境变量

使用 `env()` 函数获取安全区域边距：

```css
/* 底部固定按钮适配 */
.bottom-button {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding-bottom: env(safe-area-inset-bottom);
  background-color: #fff;
}

/* 顶部区域适配 */
.custom-header {
  padding-top: env(safe-area-inset-top);
}
```

### CSS 安全区域变量

| 变量 | 说明 |
| ---- | ---- |
| `env(safe-area-inset-top)` | 顶部安全距离 |
| `env(safe-area-inset-bottom)` | 底部安全距离 |

## 底部安全区域适配

在 iPhone X 及以上机型中，底部有 Home Indicator 区域。如果页面底部有按钮或操作栏，需要增加额外的底部间距避免被遮挡。

### 常见场景

```css
/* 底部 TabBar 适配 */
.tab-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  height: 50px;
  padding-bottom: env(safe-area-inset-bottom);
  background-color: #fff;
  border-top: 1px solid #eee;
}

/* 底部操作按钮适配 */
.action-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 12px 16px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
  background-color: #fff;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
}
```

## 自适应单位

小程序提供了多种尺寸单位，选择合适的单位可以让页面在不同屏幕上自适应。

### rpx

`rpx` 是小程序提供的响应式像素单位，会根据屏幕宽度自动换算。规定屏幕宽度为 750rpx。

| 设备 | 屏幕宽度 (px) | 1rpx 等于 |
| ---- | ------------- | --------- |
| iPhone 5 | 320px | 0.42px |
| iPhone 6/7/8 | 375px | 0.5px |
| iPhone 12/13 | 390px | 0.52px |

```css
/* 使用 rpx 实现自适应布局 */
.card {
  width: 710rpx;  /* 屏幕宽度留 20rpx 左右边距 */
  margin: 0 20rpx;
  padding: 24rpx;
  border-radius: 16rpx;
}
```

### rem

`rem` 使用物理设备宽度计算，不受横竖屏旋转影响。

### 使用建议

| 场景 | 推荐单位 |
| ---- | -------- |
| 一般布局 | `rpx` |
| 文字大小 | `rpx` 或 `px`（小字号用 px 避免模糊） |
| 边框宽度 | `px`（1px 边框不建议用 rpx） |
| 需要固定大小的元素 | `px` |

```css
/* 推荐实践 */
.title {
  font-size: 32rpx;    /* 文字用 rpx */
  line-height: 44rpx;
}

.divider {
  height: 1px;         /* 细线用 px */
  background: #eee;
}

.container {
  padding: 24rpx;      /* 间距用 rpx */
  width: 100%;
}
```