Flexbox 在 RN 中的行为差异 & css注意

RN 的样式系统是 CSS 的子集 + 变体:基于 Flexbox 布局,但默认值、继承规则、支持的属性与 Web CSS 均有差异。核心原则是不要假设 Web 写法能直接移植,遇到问题优先查阅对应组件的官方文档确认属性是否受支持。


一、Flexbox 与 Web CSS 的差异

默认值

属性 Web CSS React Native
flexDirection row column
alignContent stretch flex-start
flexShrink 1 0
position static relative

flex 简写

  • Web 的 flex: 1 等价于 flex-grow: 1; flex-shrink: 1; flex-basis: 0。
  • RN 底层由 Yoga 引擎计算,行为接近但边界情况与 W3C 规范略有出入,且不支持三值写法:
jsx 复制代码
// ❌ RN 不支持
{ flex: '1 1 auto' }

// ✅ 分开声明
{ flexGrow: 1, flexShrink: 1, flexBasis: 'auto' }

不支持的属性 📢

  • float
  • display: inline-flex
  • flex-flow(需分别写 flexDirection 和 flexWrap)
  • grid 系列属性

RN 特有属性

  • gap / rowGap / columnGap:RN 0.71+ 支持
  • aspectRatio:接受数字(1)而非字符串("1/1")

常见陷阱 📢

子 View 若未声明尺寸或 flex,高度默认为 0,不可见:

jsx 复制代码
// ❌ 子 View 高度为 0
<View style={{ flex: 1 }}>
  <View style={{ backgroundColor: 'red' }} />
</View>

// ✅ 正确
<View style={{ flex: 1 }}>
  <View style={{ flex: 1, backgroundColor: 'red' }} />
</View>

二、样式系统规范

StyleSheet API

  • RN 没有真正的 CSS,样式是 JavaScript 对象,属性名用 camelCase。
  • 推荐用 StyleSheet.create() 而非内联对象(样式会被 ID 化,减少跨线程传输开销):
jsx 复制代码
import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: { flex: 1, backgroundColor: '#fff' },
});

无 CSS 继承与选择器

RN 不支持 CSS 选择器,样式不会自动继承(Text 嵌套是例外:color、fontSize 等文字样式会从父 Text 继承):

jsx 复制代码
// ❌ View 没有 color 属性,子 Text 不会继承
<View style={{ color: 'red' }}>
  <Text>不会变红</Text>
</View>

// ✅ 每个组件单独设置
<Text style={{ color: 'red' }}>会变红</Text>

组件与样式绑定

不是所有属性对所有组件都有效:

组件 支持 不支持
View backgroundColor、border、shadow color、fontSize
Text color、fontSize、fontWeight overflow: scroll
Image width、height、resizeMode borderRadius(部分平台有问题)

单位规则

jsx 复制代码
// ✅ 无单位数字 = dp(与屏幕密度无关的像素)
{ width: 100, fontSize: 16 }

// ✅ 部分属性支持百分比字符串
{ width: '50%', height: '100%' }

// ❌ 不支持 px、rem 等单位
{ width: '100px', fontSize: '1rem' }

// ❌ 不支持 margin/padding 简写字符串
{ margin: '10 20' }

// ✅ 用 marginVertical / marginHorizontal
{ marginVertical: 10, marginHorizontal: 20 }

不支持的 CSS 功能

CSS 功能 RN 替代方案
::before / ::after 额外的 View / Text 组件
:hover / :focus Pressable 的 onHoverIn / onPressIn
transition / animation Animated API 或 react-native-reanimated
box-shadow shadow*(iOS)+ elevation(Android)
渐变背景 expo-linear-gradient 等三方库

平台差异

jsx 复制代码
import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  box: {
    shadowColor: '#000',      // iOS 阴影
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.3,
    shadowRadius: 4,
    elevation: 5,             // Android 阴影
  },
});

// 按平台差异化样式
const textStyle = Platform.select({
  ios: { fontSize: 14 },
  android: { fontSize: 13 },
});

overflow 行为

Android 默认 hidden,iOS 默认 visible。需要裁剪内容时,应明确声明以避免平台差异:

jsx 复制代码
{ overflow: 'hidden' }
相关推荐
enjoywindstorm2 天前
移动端原生框架对比评测
react native
传奇开心果编程2 天前
【声明式UI开发实用技术学与练】第8课 状态提升与下放
学习·flutter·react native·ui·swiftui·composer
传奇开心果编程3 天前
【现代声明式UI学与练】第4课 列表渲染与 key——如何高效渲染列表、key 的作用、列表重排时的状态保持
学习·flutter·react native·ui·swiftui·android jetpack
传奇开心果编程4 天前
【现代声明式UI学与练】第7课 组件通信——父传子、子传父、跨层级通信、状态提升与 Context
学习·flutter·react native·ui·swiftui·android jetpack
500844 天前
React Native for OpenHarmony 实战:三方库 react-native-url-polyfill 的鸿蒙化适配指南
javascript·react native·react.js·性能优化·electron·harmonyos
传奇开心果编程4 天前
【现代声明式UI学与练】第9课 性能优化——渲染优化、列表优化、内存优化、启动优化
学习·flutter·react native·ui·性能优化·swiftui·android jetpack
500844 天前
React Native for OpenHarmony 实战:三方库 react-native-volume-control 的鸿蒙化适配指南
javascript·react native·react.js·electron·harmonyos
500849 天前
React Native for OpenHarmony 实战:三方库 react-native-crypto-js 的鸿蒙化适配指南
javascript·react native·性能优化·electron·harmonyos
500849 天前
React Native for OpenHarmony 实战:三方库 react-native-device-name 的鸿蒙化适配指南
深度学习·react native·react.js·机器学习·harmonyos
500849 天前
React Native for OpenHarmony 实战:三方库 react-native-torch 的鸿蒙化适配指南
javascript·react native·react.js·harmonyos