React Native Responsive Design
Phones come in many sizes. A small budget device, a large flagship, a foldable, and a tablet all run the same app. A layout built for one screen can look cramped or empty on another. Responsive design means the interface adapts to the space it receives, so every user sees a clean screen.
The Screen Size Problem
Small phone Large phone Tablet ┌────────┐ ┌──────────┐ ┌────────────────┐ │ 360 px │ │ 430 px │ │ 820 px │ │ │ │ │ │ │ │ │ │ │ │ │ └────────┘ └──────────┘ └────────────────┘ Fixed 400 px box → overflows on the small phone
Hard-coded widths cause this trouble. Flexible sizing solves it.
Technique 1: Flexbox Proportions
The flex property shares space by ratio instead of fixed pixels. Two boxes with flex: 1 split the width evenly on any device.
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 1, backgroundColor: 'tomato', height: 80 }} />
<View style={{ flex: 2, backgroundColor: 'skyblue', height: 80 }} />
</View>
┌────────┬────────────────┐ │ flex 1 │ flex 2 │ Ratio 1 : 2 on every screen └────────┴────────────────┘
Technique 2: Percentage Sizes
Width and height accept percentage strings relative to the parent.
<View style={{ width: '90%', alignSelf: 'center' }}>
<Text>Always 90 percent of the parent</Text>
</View>
Technique 3: Dimensions and useWindowDimensions
Read the real screen size and calculate values from it. The useWindowDimensions hook updates automatically when the device rotates.
import { useWindowDimensions } from 'react-native';
function Banner() {
const { width, height } = useWindowDimensions();
return (
<View style={{ width: width * 0.9, height: height * 0.2 }}>
<Text>Width: {Math.round(width)}</Text>
</View>
);
}
Technique 4: Orientation Awareness
Compare width and height to detect landscape mode. A recipe app can show one column in portrait and two columns in landscape.
const { width, height } = useWindowDimensions();
const isLandscape = width > height;
<FlatList
key={isLandscape ? 'two' : 'one'}
numColumns={isLandscape ? 2 : 1}
data={recipes}
renderItem={renderRecipe}
/>
Portrait Landscape ┌──────┐ ┌──────────────┐ │ Item │ │ Item │ Item │ │ Item │ │ Item │ Item │ │ Item │ └──────────────┘ └──────┘
Technique 5: Safe Areas
Modern phones include notches, rounded corners, and gesture bars. Content that touches those zones gets clipped. Wrap screens in a safe area component so content stays inside the visible region.
import { SafeAreaView } from 'react-native-safe-area-context';
<SafeAreaView style={{ flex: 1 }}>
<Text>Content stays clear of the notch</Text>
</SafeAreaView>
Technique 6: Platform Differences
Android and iOS follow different design habits. The Platform module lets you adjust values for each.
import { Platform } from 'react-native';
const styles = {
header: {
paddingTop: Platform.OS === 'ios' ? 50 : 24,
},
shadowBox: Platform.select({
ios: { shadowOpacity: 0.2, shadowRadius: 4 },
android: { elevation: 4 },
}),
};
Scaling Text
Users change font size in system settings. React Native scales text automatically. Layouts that break at larger sizes need roomy containers, so avoid fixed heights on text boxes. Use minHeight and padding instead.
A Small Scale Helper
Many teams write a helper that scales values from a base design width of 375 pixels.
import { Dimensions } from 'react-native';
const { width } = Dimensions.get('window');
const scale = (size) => (width / 375) * size;
const styles = {
title: { fontSize: scale(20) },
card: { padding: scale(16) },
};
Testing on Many Screens
- Run the app on a small and a large emulator
- Rotate the device and watch the layout
- Raise the system font size to the maximum
- Check a device with a notch
Summary
Responsive React Native layouts rely on flexible tools. Use flex ratios and percentages for most sizing, useWindowDimensions for calculated values, safe areas for notches, and Platform for system differences. Test on several screen sizes before release.
