React Native course ยท Module 2: Lists and styles
StyleSheet - Advanced Styling
In this lesson4
StyleSheet is the foundation of styling in React Native. Let's explore advanced techniques!
Creating Styles
import { View, Text, StyleSheet } from 'react-native';
export default function StyleExample() {
return (
<View style={styles.container}>
{/* Single style */}
<Text style={styles.title}>Title</Text>
{/* Combining styles (array) */}
<Text style={[styles.text, styles.bold]}>Bold text</Text>
{/* Conditional styles */}
<Text style={[styles.text, isActive && styles.active]}>
Conditional style
</Text>
{/* Inline + StyleSheet */}
<Text style={[styles.text, { color: 'red' }]}>
Inline override
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
text: {
fontSize: 16,
},
bold: {
fontWeight: 'bold',
},
active: {
color: '#3498db',
},
});Flexbox in React Native
Flexbox works similarly to CSS, but with a few differences:
import { View, Text, StyleSheet } from 'react-native';
export default function FlexboxExample() {
return (
<View style={styles.container}>
{/* Flex direction - column by default! */}
<View style={styles.column}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box3} />
</View>
{/* Row direction */}
<View style={styles.row}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box3} />
</View>
{/* Flex grow */}
<View style={styles.row}>
<View style={[styles.box1, { flex: 1 }]} />
<View style={[styles.box2, { flex: 2 }]} />
<View style={[styles.box3, { flex: 1 }]} />
</View>
{/* Justify & Align */}
<View style={styles.centered}>
<Text style={styles.text}>Centered</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
gap: 20,
backgroundColor: '#1a5276',
},
column: {
flexDirection: 'column', // Default in RN
gap: 10,
},
row: {
flexDirection: 'row',
gap: 10,
},
centered: {
flex: 1,
justifyContent: 'center', // Main axis
alignItems: 'center', // Cross axis
backgroundColor: '#2c3e50',
borderRadius: 12,
},
box1: {
width: 60,
height: 60,
backgroundColor: '#e74c3c',
borderRadius: 8,
},
box2: {
width: 60,
height: 60,
backgroundColor: '#2ecc71',
borderRadius: 8,
},
box3: {
width: 60,
height: 60,
backgroundColor: '#3498db',
borderRadius: 8,
},
text: {
color: '#fff',
fontSize: 18,
},
});Position: absolute
import { View, Text, StyleSheet } from 'react-native';
export default function PositionExample() {
return (
<View style={styles.container}>
<View style={styles.card}>
<Text style={styles.cardTitle}>Treasure card</Text>
{/* Badge in the top right corner */}
<View style={styles.badge}>
<Text style={styles.badgeText}>NEW</Text>
</View>
{/* Icon in the bottom left corner */}
<View style={styles.icon}>
<Text>โ</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#1a5276',
},
card: {
width: 250,
height: 150,
backgroundColor: '#2c3e50',
borderRadius: 16,
padding: 20,
},
cardTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#fff',
},
badge: {
position: 'absolute',
top: -10,
right: -10,
backgroundColor: '#e74c3c',
paddingHorizontal: 10,
paddingVertical: 4,
borderRadius: 12,
},
badgeText: {
color: '#fff',
fontSize: 12,
fontWeight: 'bold',
},
icon: {
position: 'absolute',
bottom: 10,
left: 10,
width: 40,
height: 40,
backgroundColor: '#f39c12',
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
},
});Shadows
import { View, Text, StyleSheet, Platform } from 'react-native';
export default function ShadowExample() {
return (
<View style={styles.container}>
{/* iOS shadow */}
<View style={styles.cardIOS}>
<Text style={styles.text}>iOS Shadow</Text>
</View>
{/* Android shadow (elevation) */}
<View style={styles.cardAndroid}>
<Text style={styles.text}>Android Elevation</Text>
</View>
{/* Cross-platform shadow */}
<View style={styles.cardCrossplatform}>
<Text style={styles.text}>Cross-platform</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
gap: 30,
backgroundColor: '#ecf0f1',
},
cardIOS: {
width: 200,
padding: 20,
backgroundColor: '#fff',
borderRadius: 12,
// iOS only
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
},
cardAndroid: {
width: 200,
padding: 20,
backgroundColor: '#fff',
borderRadius: 12,
// Android only
elevation: 8,
},
cardCrossplatform: {
width: 200,
padding: 20,
backgroundColor: '#fff',
borderRadius: 12,
// Both platforms
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
},
android: {
elevation: 8,
},
}),
},
text: {
textAlign: 'center',
fontSize: 16,
},
});Code for this lesson: App.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.card}>
<Text style={styles.emoji}>{'><>'}</Text>
<Text style={styles.name}>Coral fish</Text>
<Text style={styles.description}>Resident of the Atlantis reefs</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#aed6f1',
},
card: {
width: 220,
padding: 20,
backgroundColor: '#fff',
alignItems: 'center',
// TODO: add borderRadius: 16 to round the card corners
// TODO: add the iOS shadow:
// shadowColor: '#000',
// shadowOffset: { width: 0, height: 4 },
// shadowOpacity: 0.25,
// shadowRadius: 8,
// TODO: add the Android shadow: elevation: 8,
},
emoji: {
fontSize: 48,
marginBottom: 8,
},
name: {
fontSize: 18,
fontWeight: '600',
color: '#2c3e50',
},
description: {
fontSize: 14,
color: '#7f8c8d',
marginTop: 4,
},
});Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. Which justifyContent value distributes items evenly with equal spacing between them?
2. What does position: 'absolute' do in React Native?
Hands-on tasks in the game
- Vertical ordering
Arrange justifyContent values from smallest to largest spacing at the edges:
- Click in order
Click the shadow properties in the correct order (iOS):
- Code editor
Complete the styles for a card with a shadow effect.