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(需分别写 flexDirectionflexWrap
  • 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 嵌套是例外:colorfontSize 等文字样式会从父 Text 继承):

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

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

组件与样式绑定

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

组件 支持 不支持
View backgroundColorbordershadow colorfontSize
Text colorfontSizefontWeight overflow: scroll
Image widthheightresizeMode 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 PressableonHoverIn / 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' }
相关推荐
CC_Amber3 小时前
浅谈 RN新架构与老架构
react native
弓.长.3 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-flash-message — 闪现消息组件
react native·react.js·harmonyos
弓.长.3 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-snap-carousel — 轮播组件
react native·react.js·harmonyos
弓.长.3 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-animatable — 动画组件
react native·react.js·harmonyos
CC_Amber4 小时前
RN线程模型
react native
弓.长.4 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-shimmer-placeholder — 骨架屏组件
react native·react.js·harmonyos
早點睡3902 天前
ReactNative项目OpenHarmony三方库集成实战:react-native-calendar-events(读取不到日历里新增的事件,待排查)
javascript·react native·react.js
早點睡3903 天前
ReactNative项目OpenHarmony三方库集成实战:react-native-render-html
react native·react.js·html
早點睡3903 天前
ReactNative项目OpenHarmony三方库集成实战:react-native-sensors(设备传感器)
javascript·react native·react.js