User interface

Styling and laying out screens with StyleSheet and Flexbox.


There's no CSS in React Native. Instead you style components with plain JavaScript objects, and lay them out with a Flexbox-based system that's similar to (but not identical to) CSS Flexbox.

Style

Most components accept a style prop. You typically define styles with StyleSheet.create — it doesn't do anything magic at runtime, but it's the conventional way to group and validate styles.

import { StyleSheet, Text, View } from "react-native";

function Card() {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>Hello</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    borderRadius: 8,
    backgroundColor: "white",
  },
  title: {
    fontSize: 20,
    fontWeight: "bold",
  },
});

Styles aren't inherited the way CSS properties are — a Text inside a View doesn't automatically pick up the View's fontSize or color. You can combine multiple styles by passing an array: style={[styles.base, styles.active]} (later styles win).

Layout with Flexbox

Every View is a flex container by default, and flexDirection defaults to column (top-to-bottom) — the opposite of the web's default row.

  • flexDirectioncolumn (default) or row, the direction children are laid out in.
  • justifyContent — aligns children along the main axis (flex-start, center, flex-end, space-between, space-around).
  • alignItems — aligns children along the cross axis (flex-start, center, flex-end, stretch).
  • flex: 1 — makes a component grow to fill the remaining available space.
import { View } from "react-native";

function Row() {
  return (
    <View style={{ flexDirection: "row", justifyContent: "space-between" }}>
      <View style={{ width: 50, height: 50, backgroundColor: "tomato" }} />
      <View style={{ width: 50, height: 50, backgroundColor: "skyblue" }} />
    </View>
  );
}

Height and width

A component's size can be set explicitly with fixed width/height, or made flexible with flex. Unlike the web, numeric dimensions have no unit — they're density-independent pixels.

// fixed size
<View style={{ width: 100, height: 100 }} />;

// takes up all remaining space in its parent
<View style={{ flex: 1 }} />;

Platform-specific styling

Sometimes a value needs to differ between iOS and Android. Platform.OS and Platform.select let you branch on the current platform.

import { Platform, StyleSheet } from "react-native";

const styles = StyleSheet.create({
  container: {
    paddingTop: Platform.OS === "android" ? 24 : 0,
    ...Platform.select({
      ios: { shadowOpacity: 0.2 },
      android: { elevation: 4 },
    }),
  },
});

Handling touches

Wrap anything that should respond to touches in Pressable. Button covers the common case with a ready-made native look, but is hard to customize — reach for Pressable whenever you need your own styling.