Direction Flexbox, JustifyContent et AlignItems
Contrôlez la disposition des éléments enfants dans une View avec flexDirection, justifyContent et alignItems pour centrer, espacer et aligner les éléments.
Direction Flexbox, JustifyContent et AlignItems est une leçon React Native Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage React Native Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours React Native Academy comprend 4 leçons au total.
Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.
Flexbox Is the Default Layout System
React Native uses Flexbox as its layout algorithm for every View component — there is no block or inline layout like in CSS. Every View is automatically a Flex container, meaning its children are positioned according to Flexbox rules by default. The key difference from web CSS Flexbox is that React Native's default flexDirection is 'column', not 'row' like on the web. This means children stack vertically by default, which matches how most mobile screens are laid out.
import { View, StyleSheet } from 'react-native';
export default function DefaultFlex() {
return (
// No flexDirection needed — 'column' is the default
<View style={styles.container}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box3} />
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#f5f5f5', padding: 16 },
box1: { height: 60, backgroundColor: '#ff6b6b', marginBottom: 8 },
box2: { height: 60, backgroundColor: '#4f86f7', marginBottom: 8 },
box3: { height: 60, backgroundColor: '#51cf66' },
});flexDirection: row vs column
flexDirection sets the main axis of the Flex container. With 'column' (default), children stack top to bottom. With 'row', children sit left to right. The values 'column-reverse' and 'row-reverse' reverse the order. Changing flexDirection also changes which axis justifyContent and alignItems affect — justifyContent always works along the main axis, and alignItems along the cross axis. This is the single most impactful Flexbox property to understand.
import { View, StyleSheet } from 'react-native';
export default function DirectionDemo() {
return (
<View style={{ flex: 1, gap: 16, padding: 16 }}>
{/* Column: children stack vertically (default) */}
<View style={{ flexDirection: 'column', height: 120, backgroundColor: '#f0f0f0' }}>
<View style={styles.box} />
<View style={styles.box} />
</View>
{/* Row: children sit side by side */}
<View style={{ flexDirection: 'row', height: 60, backgroundColor: '#f0f0f0' }}>
<View style={styles.box} />
<View style={styles.box} />
</View>
</View>
);
}
const styles = StyleSheet.create({
box: { width: 50, height: 50, backgroundColor: '#4f86f7', margin: 4 },
});justifyContent: Aligning Along the Main Axis
justifyContent controls how children are distributed along the main axis (vertical for column, horizontal for row). The most useful values are: 'flex-start' (pack at start, default), 'flex-end' (pack at end), 'center' (center the group), 'space-between' (first and last touch the edges, equal gaps between others), 'space-around' (equal space around each child), and 'space-evenly' (equal space including edges). 'space-between' is particularly common for navigation bars and action button rows.
import { View, Text, StyleSheet } from 'react-native';
export default function SpaceBetween() {
return (
<View style={styles.row}>
<Text style={styles.tab}>Home</Text>
<Text style={styles.tab}>Search</Text>
<Text style={styles.tab}>Profile</Text>
</View>
);
}
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
justifyContent: 'space-between', // distribute across full width
paddingHorizontal: 24,
paddingVertical: 16,
backgroundColor: '#fff',
borderTopWidth: 1,
borderTopColor: '#eee',
},
tab: { fontSize: 14, color: '#666' },
});alignItems: Aligning Along the Cross Axis
alignItems controls how children are positioned on the cross axis (perpendicular to the main axis). For a column container it aligns children horizontally; for a row container it aligns them vertically. Values: 'flex-start' (default for column on Android, items hug the start), 'flex-end', 'center', and 'stretch' (items expand to fill the cross axis — this is the default on iOS and makes sense for column layouts where you want full-width children). 'baseline' aligns text baselines of children.
import { View, Text, StyleSheet } from 'react-native';
export default function AlignDemo() {
return (
<View style={styles.container}>
{/* Row: alignItems centers children vertically */}
<View style={styles.row}>
<Text style={styles.smallText}>Small</Text>
<Text style={styles.largeText}>LARGE</Text>
<Text style={styles.smallText}>Small</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, padding: 20 },
row: {
flexDirection: 'row',
alignItems: 'center', // vertically center all items
backgroundColor: '#e8f0fe',
padding: 16,
borderRadius: 8,
},
smallText: { fontSize: 12, color: '#666', marginHorizontal: 8 },
largeText: { fontSize: 28, fontWeight: 'bold', color: '#111', marginHorizontal: 8 },
});Centering Content with flex, justify, and align
A very common pattern is centering content both vertically and horizontally — for splash screens, empty states, or loading indicators. Set the container to flex: 1 so it fills available space, then apply justifyContent: 'center' and alignItems: 'center'. Since the default flexDirection is column, this centers children in the middle of the screen both vertically and horizontally. This three-property combination is probably the most-used layout recipe in React Native.
import { View, Text, StyleSheet } from 'react-native';
export default function CenteredScreen() {
return (
<View style={styles.container}>
<Text style={styles.emoji}>🎯</Text>
<Text style={styles.title}>Nothing here yet</Text>
<Text style={styles.subtitle}>Add your first item to get started</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center', // vertical center (column main axis)
alignItems: 'center', // horizontal center (column cross axis)
backgroundColor: '#f8f9fa',
},
emoji: { fontSize: 56, marginBottom: 16 },
title: { fontSize: 22, fontWeight: 'bold', color: '#333' },
subtitle: { fontSize: 14, color: '#999', marginTop: 8, textAlign: 'center' },
});alignSelf: Overriding Cross-Axis Alignment
alignSelf overrides the parent's alignItems for a specific child. It accepts the same values as alignItems: 'auto' (use parent's setting), 'flex-start', 'flex-end', 'center', and 'stretch'. This is useful when most siblings share one alignment but one child needs different treatment — for example, a row of icons where one is larger and should align to the top while the others center. Use alignSelf sparingly; it's more maintainable to adjust the parent's alignItems and use wrapper Views when needed.
import { View, Text, StyleSheet } from 'react-native';
export default function AlignSelfExample() {
return (
<View style={styles.row}>
<View style={styles.boxSmall} />
{/* This box aligns to flex-end independently */}
<View style={[styles.boxSmall, { alignSelf: 'flex-end', backgroundColor: 'red' }]} />
<View style={styles.boxSmall} />
</View>
);
}
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
alignItems: 'center', // default for siblings
height: 100,
backgroundColor: '#e8f0fe',
padding: 8,
gap: 8,
},
boxSmall: { width: 50, height: 50, backgroundColor: '#4f86f7', borderRadius: 6 },
});gap, rowGap, and columnGap
Instead of adding margin to each child, use gap on the container to set uniform spacing between flex children. gap sets both row and column gaps, while rowGap and columnGap control them independently. This eliminates the need for marginBottom on all but the last child, or the hack of adding negative margin to the container. Gap support was added in React Native 0.71 (available in Expo SDK 48+), so check your RN version before using it in older projects.
import { View, StyleSheet } from 'react-native';
export default function GapExample() {
return (
<View style={styles.container}>
{[1, 2, 3, 4].map(n => (
<View key={n} style={styles.card} />
))}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
gap: 12, // equal gap between all children
padding: 16,
backgroundColor: '#f5f5f5',
},
card: {
width: '47%', // two columns
height: 100,
backgroundColor: '#4f86f7',
borderRadius: 10,
},
});flexWrap: Wrapping Children to Next Lines
By default, flex children shrink to fit in a single line and never wrap. Set flexWrap: 'wrap' on the container to let children wrap to the next row (for row direction) or next column (for column direction) when they run out of space. This is the foundation for tag clouds, grid-like layouts with percentage widths, and any UI where items should flow onto the next line naturally. 'nowrap' is the default; 'wrap-reverse' wraps in the opposite direction.
import { View, Text, StyleSheet } from 'react-native';
const tags = ['React Native', 'Mobile', 'iOS', 'Android', 'JavaScript', 'Flexbox', 'Expo'];
export default function TagCloud() {
return (
<View style={styles.container}>
{tags.map(tag => (
<View key={tag} style={styles.tag}>
<Text style={styles.tagText}>{tag}</Text>
</View>
))}
</View>
);
}
const styles = StyleSheet.create({
container: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, padding: 16 },
tag: { backgroundColor: '#e8f0fe', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 16 },
tagText: { color: '#4f86f7', fontSize: 13, fontWeight: '500' },
});A Practical Header Layout
Apply your Flexbox knowledge to build a common mobile app pattern: a navigation header with a back button on the left, a centered title, and a menu icon on the right. Use flexDirection: 'row' and alignItems: 'center' on the header container. Give the title flex: 1 so it expands to fill the remaining space and centers itself between the fixed-width side icons. This is cleaner than using position: 'absolute' for centering and handles varying title lengths correctly.
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default function Header({ title, onBack, onMenu }) {
return (
<View style={styles.header}>
<TouchableOpacity style={styles.sideBtn} onPress={onBack}>
<Text style={styles.icon}>←</Text>
</TouchableOpacity>
<Text style={styles.title} numberOfLines={1}>{title}</Text>
<TouchableOpacity style={styles.sideBtn} onPress={onMenu}>
<Text style={styles.icon}>⋯</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
header: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 16,
paddingVertical: 12,
backgroundColor: '#fff',
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#ddd',
},
sideBtn: { width: 40, alignItems: 'center' },
title: { flex: 1, fontSize: 18, fontWeight: '600', color: '#111', textAlign: 'center' },
icon: { fontSize: 22, color: '#333' },
});Debugging Flexbox Layouts
Flexbox bugs are common during layout development. Useful debugging techniques: add a temporary backgroundColor to each View to make its boundaries visible, use React DevTools to inspect the computed layout in the component tree, check whether flex: 1 is missing from ancestor containers (a container without flex: 1 collapses to zero height, making its children invisible), and verify that flexDirection is the value you intend (remember, React Native defaults to column, not row). Removing all styles and adding them back one by one is a reliable way to isolate layout bugs.
// Debug technique: color-code your Views temporarily
const debugStyles = StyleSheet.create({
container: { flex: 1, backgroundColor: 'rgba(255,0,0,0.1)' }, // red tint
inner: { backgroundColor: 'rgba(0,0,255,0.1)' }, // blue tint
text: { backgroundColor: 'rgba(0,255,0,0.1)' }, // green tint
});
// Then you can see exactly where each View starts and ends
// Remove these debug colors before shipping!Row with Icon, Text, and Action
One of the most common mobile UI patterns is a list row with an icon on the left, text in the middle, and an action button on the right. Implement it with flexDirection: 'row' on the container, alignItems: 'center' to vertically align all children, a fixed-size icon View on the left, a flex: 1 text area in the middle (so it expands to fill available space), and a fixed-size action button on the right. This pattern appears in settings screens, contact lists, and any data-dense table view in mobile apps.
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default function SettingsRow({ icon, label, subtitle, onPress }) {
return (
<TouchableOpacity style={styles.row} onPress={onPress}>
{/* Left: icon */}
<View style={styles.iconContainer}>
<Text style={{ fontSize: 22 }}>{icon}</Text>
</View>
{/* Middle: text content — flex: 1 fills space */}
<View style={{ flex: 1 }}>
<Text style={styles.label} numberOfLines={1}>{label}</Text>
{subtitle && <Text style={styles.subtitle} numberOfLines={1}>{subtitle}</Text>}
</View>
{/* Right: chevron */}
<Text style={styles.chevron}>›</Text>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
row: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, backgroundColor: '#fff', gap: 12 },
iconContainer: { width: 36, height: 36, borderRadius: 8, backgroundColor: '#f0f4ff', alignItems: 'center', justifyContent: 'center' },
label: { fontSize: 16, color: '#222' },
subtitle: { fontSize: 13, color: '#999', marginTop: 2 },
chevron: { fontSize: 22, color: '#ccc', fontWeight: '300' },
});Quick Check
Test your understanding of React Native Mobile Development concepts from this lesson.
Lesson Recap
In this lesson you learned: flexDirection sets the main axis (column by default in React Native, not row), justifyContent distributes children along the main axis, and alignItems aligns children on the cross axis. Next up we explore the flex property and responsive sizing across screen dimensions.
Questions Fréquemment Posées
La leçon « Direction Flexbox, JustifyContent et AlignItems » est-elle gratuite ?
Oui — le texte complet de « Direction Flexbox, JustifyContent et AlignItems » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours React Native Academy, passe à CoddyKit PRO. Le cours React Native Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Direction Flexbox, JustifyContent et AlignItems » ?
Contrôlez la disposition des éléments enfants dans une View avec flexDirection, justifyContent et alignItems pour centrer, espacer et aligner les éléments. Tu pratiques React Native Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer React Native Academy ?
Aucune expérience préalable n'est requise. React Native Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Direction Flexbox, JustifyContent et AlignItems » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon React Native Academy ?
Oui. Chaque leçon React Native Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- StyleSheet.create et styles intégrés
- Direction Flexbox, JustifyContent et AlignItems
- flex, flexGrow et dimensionnement réactif
- Construire une grille de cartes réactive