React Native Styling & Layout

React Native doesn't use CSS files or the browser's layout engine. Styles are JavaScript objects with camelCased properties (backgroundColor, marginTop), and layout uses Flexbox implemented by the Yoga engine, which maps to native views on iOS and Android. If you know CSS Flexbox, most of it transfers, with a few important differences in defaults and units.

Mobile adds its own concerns: notches and home indicators (safe areas), wildly varying screen sizes and densities, platform conventions that differ between iOS and Android, users' font scaling preferences, and dark mode. This page covers styling fundamentals and the patterns and libraries teams use to keep styles consistent.

TL;DR

Quick Example

Core Concepts

Styles as Objects

Units

Numbers are density-independent pixels (points on iOS, dp on Android): width: 100 looks the same physical size across screen densities. Percentages work for dimensions and positions (width: '50%'). There are no em, rem, or vh units. Use useWindowDimensions() for screen-relative sizing, and PixelRatio for pixel-precise work (hairlines: StyleSheet.hairlineWidth).

Flexbox With Yoga

React Native layouts are Flexbox, with differences from the web:

gap, rowGap, and columnGap are supported. Every View is a flex container, and there's no display: block, grid, or floats. position: 'absolute' works relative to the parent. See CSS Flexbox for the core model.

Responsive Layouts

Safe Areas

Notches, Dynamic Island, rounded corners, status bars, and home indicators obscure parts of the screen. react-native-safe-area-context provides SafeAreaView (with configurable edges) and useSafeAreaInsets() for precise padding. Navigation libraries integrate with it, and Android's edge-to-edge display is now the norm, so insets matter on both platforms.

Platform Differences

Dark Mode and Theming

useColorScheme() returns 'light', 'dark', or null, and updates when the system theme changes. Build a theme object (colors, spacing, typography tokens) provided via context, or use a styling library with theming support. Set status bar style accordingly. See dark mode theming and design tokens.

Typography and Font Scaling

Users can increase system font size, and <Text> respects it by default (allowFontScaling). Design layouts that grow with larger text (avoid fixed heights on text containers), cap extreme scaling with maxFontSizeMultiplier only where necessary, and test with accessibility sizes. Custom fonts load via Expo Font or native linking. See accessibility.

Styling Libraries

Best Practices

Centralize Design Tokens

Define colors, spacing, radii, and typography once (a theme object or library tokens), and use them everywhere. It makes dark mode and rebranding simple, and keeps UI consistent.

Build Primitives

Create Box, Text, Button, Card, and Screen components that apply tokens, safe areas, and accessibility defaults. Screens then compose primitives rather than repeating raw styles.

Test on Real Devices and Sizes

Check small phones, large phones, tablets, both platforms, landscape orientation, dark mode, and large font sizes. Simulators miss performance and some rendering differences.

Keep Touch Targets Large

Pressable elements should be at least about 44×44 pt (iOS) or 48×48 dp (Android). Use hitSlop to extend small icons' touch areas.

Common Mistakes

Forgetting flex: 1 on Containers

A screen whose root View lacks flex: 1 (or a height) collapses to its content, so scroll views and backgrounds don't fill the screen.

Hard-Coding Status Bar Heights

Assuming a 20pt or 44pt status bar breaks on notched devices, Dynamic Island, Android cutouts, and edge-to-edge layouts. Use safe area insets.

Fixed-Height Text Containers

Buttons and list rows with fixed heights clip text when users enable larger fonts. Let content define height, with padding and minimum heights.

FAQ

Does React Native use CSS?

No. It uses JavaScript style objects with CSS-like property names in camelCase, and a subset of CSS behavior. Layout is Flexbox via Yoga. Libraries like NativeWind let you write Tailwind classes that compile to React Native styles.

Why is the default flex direction column?

Mobile screens are typically laid out vertically, so React Native defaults flexDirection to column. Set flexDirection: 'row' for horizontal arrangements.

How do I handle the notch and home indicator?

Use react-native-safe-area-context: wrap screens in SafeAreaView (choosing which edges to pad), or apply useSafeAreaInsets() values as padding. Navigation libraries typically handle headers and tab bars for you.

How do I implement dark mode in React Native?

Read the system preference with useColorScheme(), select colors from light and dark theme objects (usually via context or a styling library), and update the status bar style. Test all screens in both modes, including images and third-party components.

Related Topics

References