Skip to content
雲里
里雾

Flexbox 与 RN 布局

mindgym 开发 更新于 2026/4/12

Flexbox 是 React Native 的默认布局引擎,由 Facebook 用 C++ 写的 Yoga 引擎实现。本页从 Flexbox 的设计动机出发,梳理主轴/交叉轴的心智模型、六大核心属性的完整选项、RN 与 Web CSS 的关键差异,以及 Web display: block/inline 在 RN 中被简化掉的原因。


概述:为什么选 Flexbox

跨平台 UI 布局有两大流派:

React Native 选了 Flexbox,核心原因是它与 React 组件树的嵌套结构天然契合:容器 → 子元素的关系直接映射到父组件 → 子组件。约束模型需要引用兄弟元素的 ID 建立约束链,这和 React 的单向数据流冲突——组件不应该知道兄弟组件的存在。

RN 的布局引擎叫 Yoga,是 Facebook 用 C++ 写的跨平台 Flexbox 实现。所有 View 的位置都由 Yoga 在 native 侧统一计算,iOS 和 Android 布局结果完全一致,不需要各写一套。


工作方式:主轴与交叉轴

Flexbox 的一切围绕两根轴展开:主轴由 flexDirection 定义,交叉轴垂直于主轴。

flexDirection: row (Web 默认)        flexDirection: column (RN 默认)
─────────────────────────────       ─────────────────────────────
主轴 →    [A] [B] [C]               主轴 ↓    [A]
交叉轴 ↓                                     [B]
                                            [C]
                                    交叉轴 →

Web 默认 row 因为网页最早是水平文档流;RN 默认 column 因为手机屏幕是竖的、内容自上而下是主流。这是两个平台不同默认值的根本原因。

六大核心属性

flexDirection — 主轴方向

行为
column (RN 默认)主轴向下
column-reverse主轴向上
row (Web 默认)主轴向右
row-reverse主轴向左

-reverse 的实用场景主要是 RTL 布局(阿拉伯语/希伯来语),RN 一般用 I18nManager 处理而非手动写 reverse。

justifyContent — 主轴对齐

控制剩余空间在主轴方向如何分配:

flex-start (默认)    [A][B][C]
flex-end                              [A][B][C]
center                    [A][B][C]
space-between        [A]          [B]          [C]
space-around            [A]      [B]      [C]
space-evenly              [A]    [B]    [C]

三种 space-* 的差别记忆法:

alignItems — 交叉轴对齐

行为
stretch (RN 默认)子元素拉伸到容器交叉轴尺寸(前提:子元素未设该方向尺寸)
flex-start贴交叉轴起点
flex-end贴交叉轴终点
center交叉轴居中
baseline按文字基线对齐

stretch 陷阱:子 View 没设尺寸时会被拉伸到父容器尺寸。这是 RN 里很多”莫名撑满”问题的根源。

alignSelf — 单个子元素的对齐覆盖

作用在子元素上,覆盖父级的 alignItems。选项同 alignItems,多一个 auto(默认,继承父级)。

Android 类比:父级 gravity vs 子 View 的 layout_gravity

flex — 伸缩比例

flex: 1 是三个属性的简写:

属性作用默认值(RN)
flexGrow剩余空间的分配比例0
flexShrink空间不足时的收缩比例1
flexBasis伸缩的起始尺寸auto

Android layout_weight 只有分配比例一个维度,flex 多了 shrink 和 basis。

flexWrap — 换行策略

行为
nowrap (默认)不换行,挤在一行
wrap空间不足时换行
wrap-reverse反向换行,新行在上

RN 与 Web CSS 的三大差异

1. 默认 flexDirection 不同

2. stretch 的影响更明显

RN 里所有 View 都是 flex 容器,alignItems: stretch 的默认行为会让没设尺寸的子元素撑满交叉轴。Web 上因为有很多 inline 元素,stretch 影响不明显。

3. 没有 display: block/inline/inline-block

这是最本质的差异。Web 有三种显示模式:

display行为
block独占一行,可设宽高,默认撑满父容器
inline不换行,不可设宽高,宽度等于内容
inline-block不换行,但可设宽高

Web 需要这套模型是因为其根基是文档流——早期网页是论文、新闻、博客,内容自上而下流动,标题段落是块级(独占一行),链接粗体是行内(嵌在句子里):

<p>这是一段话,里面有一个 <a href="...">链接</a> 和一个 <strong>粗体</strong> 词。</p>

RN 的根基不是文档流,是UI 组件树。所有 <View> 默认就是 Flex 容器,通过 flexDirection 控制排列方向。RN 里只有 <Text> 嵌套时才有类似 inline 的流动行为。

本质区别

这是 NativeWind 没有 block / inline 类名的原因——它们在 RN 里没有语义。


CSS → StyleSheet → NativeWind 三层映射

同一布局的三种写法:

/* Web CSS */
.container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  gap: 8px;
}
// RN StyleSheet
const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',  // RN 不需要 display: flex
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: 16,           // 数字,无 px 单位
    gap: 8,
  },
})
// NativeWind
<View className="flex-row justify-between items-center p-4 gap-2" />

常用属性对照表

CSSStyleSheetNativeWind
display: flex无需(RN 默认)无需
flex-direction: rowflexDirection: 'row'flex-row
justify-content: space-betweenjustifyContent: 'space-between'justify-between
align-items: centeralignItems: 'center'items-center
flex: 1flex: 1flex-1
flex-wrap: wrapflexWrap: 'wrap'flex-wrap
gap: 8pxgap: 8gap-2 (4px 基数)

NativeWind 的间距基数默认是 4px:p-4 = 16px,p-2 = 8px。


常见踩坑点

坑 1:忘记 RN 默认 column —— 想让按钮水平排列但没加 flex-row,结果按钮竖着排。

坑 2:stretch 撑满陷阱 —— Text 的背景色撑满整个父容器,因为默认 alignItems: stretch 横向拉伸。修复:父级加 items-start 或给子元素明确尺寸。

坑 3:flex-1 意外吃空间 —— 三个子元素中只有一个写 flex-1,它会吃掉所有剩余空间把其他挤到最小。要均分就三个都写 flex-1


参见


参考

  1. W3C CSS Flexbox 规范 — 权威标准,理解浏览器行为边缘情况
  2. Yoga 官方仓库 — RN 布局引擎源码(C++)
  3. A Complete Guide to Flexbox (CSS-Tricks) — 经典图解教程
  4. React Native 官方布局文档 — RN 特有差异和 API