Les styles en React Native
Styles inspirées du CSS et adaptés avec Javascript
En React Native, le style des composants s’inspire du CSS mais s’exprime en JavaScript via la
prop style. On peut utiliser des styles inline, des objets créés avec StyleSheet.create, ou combiner plusieurs styles avec des tableaux.
On aura l'occasion de voir en détail la notion de prop plus loin dans ce cours. Pour le moment, dites vous qu'une prop est un peu comme un attribut que l'on applique à un composant.
Les propriétés des styles suivent le camelCase qui caractérise la syntaxe Javascript (par exemple: fontSize, backgroundColor...). Les valeurs exprimées avec des unités en CSS comme
border-width:1px sont
unitless en React Native. C'est à dire que les valeurs de ces propriétés-là sont exprimées sans unité comme
borderWidth:1 .
Pour des interfaces plus modulaires et dynamiques, on peut intégrer des bibliothèques comme
styled-components,
NativeWind ou
react-native-paper, qui facilitent la thématisation et la réutilisation. Le styling en React Native est donc à la fois souple, performant et adapté aux contraintes mobiles.
Comment React Native traite-t-il les valeurs qui décrivent des dimensions?
On sait que React Native est unitless, ce qui signifie que les valeurs de propriétés qui décrivent des dimensions sont exprimées sous forme numérique sans unité. Cependant, certaines propriétés peuvent admettre plusieurs types d'unités comme px, pt, em... Donc, comment React Native décide-t-il de l'unité à appliquer?
En React Native, les dimensions des composants (telles que width, height, margin, padding, borderWidth ou fontSize) sont exprimées en unités abstraites sans suffixe, interprétées comme des pixels indépendants de la densité. Sur Android, ces valeurs correspondent à des scale-independent pixels (sp) pour le texte, ce qui permet de respecter les préférences d’accessibilité de l’utilisateur. Sur iOS, elles sont traduites en points typographiques (pt). Cette abstraction permet à React Native d’unifier le rendu visuel entre plateformes en garantissant une apparence cohérente quel que soit l’écran ou la densité.
Si vous voulez en savoir davantage, je vous suggère ce lien sur le
site officiel de React Native qui décrit la manière dont les valeurs des propriétés width et height sont calculées. Dans tous les cas, si vous n'avez pas bien compris la théorie derrière le calcul des dimensions, ce n'est pas grave. Avec les exemples et la pratique vous saurez maitriser l'apparence des composants.
Appliquer les styles au composants
Flexbox - Disposition des layouts par défaut en React Native
React Native repose entièrement sur
Flexbox pour gérer la disposition des éléments à l’écran. Chaque composant, comme
View ou
Text, est positionné selon un système de boîtes flexibles. Par défaut, les éléments sont organisés en colonne (flexDirection: 'column'), mais on peut facilement les aligner horizontalement (row), répartir l’espace (justifyContent), ou gérer l’alignement vertical (alignItems). Ce système permet de créer des interfaces adaptables à toutes les tailles d’écran, avec une logique unifiée entre Android et iOS.
Inline style
Le inline style en React Native désigne l’application directe de styles à un composant via la prop style sous forme d’un objet JavaScript. C’est l’équivalent de l’attribut style en HTML, mais adapté à la syntaxe JavaScript.
Exemple:
import { View, Text } from 'react-native';
export default function App() {
return (
<View style={
{flex: 1,
alignItems:"center",
justifyContent:"center"}
}>
<Text style={
{fontSize:20,
color:"#0000FF"}
}>Bonjour</Text>
</View>
);
}
Pour appliquer l'inline style, on invoque un objet Javascript en se servant de l'interpolation JSX. Par défaut, le style flex est appliqué au core component
View avec une disposition en colonne, mais il faut préciser l'alignement de l'axe principale et l'axe secondaire. C'est pour cela qu'on a précisé alignItems et justifyContent. Si on oubliait de les spécifier, le contenu (les éléments imbriqués dans le composant View) serait placé en haut de l'écran.
Concernant le composant
Text, nous avons spécifié le style fontSize (taille du texte) avec la valeur 20 (unitless) et une couleur bleue.
Après exécution, on aura un résultat qui ressemble à ceci:
Méthode StyleSheet.create
La méthode
StyleSheet.create (de l'objet natif StyleSheet) est une méthode fournie par React Native pour définir et organiser les styles de manière optimisée. Plutôt que d’écrire des styles inline, on regroupe les styles dans un objet dédié, ce qui améliore la lisibilité, la réutilisabilité et les performances.
Appliquons les même styles de l'exemple précédent, mais cette fois à l'aide de la méthode StyleSheet.create:
import { StyleSheet, View, Text } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text style={styles.text}>Bonjour</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
text:{
color:"#0000FF",
fontSize:20
}
});
La méthode StyleSheet.create() se place en dehors du composant React juste après les imports et avant ou après la déclaration du composant, selon notre préférence de structure. Mais on préfère généralement l'insérer après la déclaration du composant.
Il ne faut pas oublier d'importer le module
StyleSheet (au côté d'autres composants requis) depuis la librairie
react-native:
import { StyleSheet, View, Text } from 'react-native';
La méthode StyleSheet.create() contient un objet JavaScript qui définit un ensemble de styles nommés, chacun étant lui-même un objet de propriétés de style. La méthode StyleSheet.create retourne un objet (que nous avons appelé
styles dans cet exemple).
Il suffit ensuite d'invoquer le style au sein du composant voulu à l'aide la prop
style:
<View style={styles.container}>
<Text style={styles.text}>Bonjour</Text>
</View>
Tableaux de styles
Les tableaux de styles en React Native permettent de combiner plusieurs styles dans une seule prop style. C’est une fonctionnalité puissante et souple, très utile pour appliquer des styles conditionnels ou superposés.
Exemple:
import { StyleSheet, View, Text } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text style={[styles.text, styles.text2]}>
Bonjour
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
text:{
color:"#0000FF",
fontSize:20
},
text2:{
borderWidth:1,
fontFamily:"sans-serif"
}
});
Dans ce cas, nous avons appliqué à la fois les styles
text et
text2 sur le composant
Text. Ce qui donne ce résultat:
Il est toutefois possible d'appliquer des styles conditionnels, c'est à dire des styles qui s'appliquent au composants une fois une condition réalisée. Ce qui est un peu similaire aux pseudo-classes en CSS.
La notions de pseudo-classes que l'on trouve en CSS est absente en React Native. Or, on peut les simuler avec des states comme on le fera dans l'exemple qui va suivre.
Imaginons que l'on souhaite intégrer un bouton en dessous de notre texte. On imagine qu'initialement le texte n'a pas de bordure (style text2 non appliqué). Par contre, une fois on clique sur le bouton, la bordure apparaitra.
Je propose le code suivante:
import { useState } from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
export default function App() {
const [border,setBorder]=useState(false)
const handleBorder=()=>{
setBorder(true)
}
return (
<View style={styles.container}>
<Text style={
[styles.text, border && styles.text2]
}>
Bonjour
</Text>
<Button title="Ajouter une bordure"
onPress={handleBorder} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
text:{
color:"#0000FF",
fontSize:20
},
text2:{
borderWidth:1,
fontFamily:"sans-serif"
}
});
Dans ce cas, nous avons spécifié une condition avant d'appliquer le style text2 comme ceci:
[styles.text, border && styles.text2]
Le state
border est initialisé à
false. Quand on presse le bouton, il passe à
true. C'est à ce moment là que le style
text2 est appliqué.
Ce genre d'écriture conditionnelle border&& styles.text2 est très courante en React et React Native. On l'applique souvent à des composants afin de décider si on doit les afficher ou non. Nous aurons l'occasion de traiter l'affichage conditionnel et itératif en React Native plus loin dans ce cours.
L'attribut contentContainerStyle
Dans un composant
ScrollView, la propriété
contentContainerStyle permet de styliser la zone qui contient les éléments scrollables, et non le cadre extérieur du scroll. Contrairement à
style qui s’applique à la coque du ScrollView, contentContainerStyle agit sur l’organisation interne. C’est là que l’on définit des propriétés comme padding, gap, alignItems ou justifyContent, qui influencent directement la disposition des enfants. Sans cette distinction, les styles de layout risquent d’être ignorés ou mal appliqués, ce qui peut provoquer des erreurs ou des comportements inattendus dans l’interface.
Exemple:
import { ScrollView, StyleSheet } from 'react-native';
export default function App() {
return (
<ScrollView
style={styles.container}
contentContainerStyle={styles.content}>
Contenu de ScrollView
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f2f2f2',
},
content: {
padding: 20,
gap: 10,
}
});
Dans ce cas,
style s’applique au cadre extérieur du ScrollView, c’est-à-dire à la vue scrollable elle-même (flex: 1 signifie que le ScrollView prend tout l’espace disponible et backgroundColor applique la couleur de fond du cadre scrollable). Par contre
contentContainerStyle s’applique à la zone interne qui contient les enfants du ScrollView (padding ajoute de l’espace autour du contenu et gap applique l'espace entre les éléments enfants (s'il y en a plusieurs).
En plus du composnt ScrollView, contentContainerStyle s’applique aussi à FlatList et SectionList, c'est à dire uniquement des composants scrollables qui ont une vue interne contenant les enfants.
Page 11
Styler une application React Native