Choix rapide : dans Expo, utilisez expo-linear-gradient. Dans React Native bare, utilisez react-native-linear-gradient. Installez celui qui correspond à votre stack, puis affichez un LinearGradient par colors et un dimensionné style (généralement flex: 1 pour un arrière-plan).
Expo
bunx expo install expo-linear-gradient
React Native Bare
bun add react-native-linear-gradient
Utilisation minimale (même idée dans les deux bibliothèques : export nommé depuis Expo, import par défaut depuis Bare).
import { LinearGradient } from 'expo-linear-gradient';
// Bare: import LinearGradient from 'react-native-linear-gradient';
<LinearGradient colors={['#0f172a', '#2563eb']} style={{ flex: 1 }} />;
Si vous hésitez entre des stacks natives et une coquille web-first, React Native vs Capacitor décrit les compromis qui intéressent les équipes Capgo. Le reste de cet article aborde les fonds, les boutons, les masques, les animations et le dépannage.
Table des matières
- Pourquoi votre app React Native a besoin de gradients
- Choisir sa voie : configuration Expo vs Bare React Native
- Techniques de gradient essentielles pour l'UI
- Donner vie aux gradients avec des animations
- Performance, accessibilité et spécificités des plateformes
- Dépannage et bonnes pratiques finales
Pourquoi votre app React Native a besoin de gradients
Beaucoup d'interfaces mobiles pêchent pour la même raison. Le layout est correct, l'espacement est bon, la typographie est acceptable, mais l'écran paraît toujours sans vie. Les aplats de couleur donnent l'impression que tout est un placeholder, à moins que le reste du système visuel ne soit très travaillé.
Un dégradé linéaire avec React Native Le composant règle cela avec très peu de code. Cela ajoute de la profondeur, crée une séparation entre les sections et donne un poids visuel clair aux éléments prioritaires. Un bon background en gradient peut donner à un écran de connexion un aspect abouti. Un bon bouton en gradient peut rendre l'action principale évidente sans recourir à des ombres lourdes ou des bordures trop marquées.
En 2019, expo-linear-gradient et react-native-linear-gradient étaient présents dans plus de 42 % des projets React Native, ce qui prouve que les dégradés ne sont plus un effet de niche. Ils font partie des outils UI standards des apps en production, et non d'une simple décoration ajoutée à la fin, comme l'indique cet article sur l'adoption des dégradés dans React Native.
Ce que les dégradés font bien
- Créer de la profondeur : Un écran avec un fond plat semble souvent inachevé. Un mélange subtil de haut en bas donne une impression de couches superposées.
- Guider l'attention : Les CTA principaux, les cartes d'onboarding et les headers se démarquent sans ajouter de bruit visuel.
- Remplacer les assets d'images : Dans de nombreux cas, un dégradé apporte une finition soignée sans avoir à livrer d'images de fond supplémentaires.
Règle pratique : Utilisez les dégradés là où la hiérarchie compte. Les arrière-plans, les cartes hero, les surfaces de CTA et les overlays média en profitent le plus. Les champs de formulaire, les listes denses et les conteneurs de texte courant, généralement pas.
Il y a aussi un angle design produit ici. Les équipes qui travaillent sur plusieurs plateformes passent déjà du temps à essayer de garder des interfaces cohérentes. Si ça fait partie de votre stack, ces pratiques UI et UX multiplateforme pour les applications mobiles s'alignent bien avec la même logique : moins d'assets, plus de surfaces réutilisables et des systèmes visuels qui tiennent sur tous les écrans.
Choisir sa voie : configuration Expo vs Bare React Native
C'est ce choix qui pose le plus de problèmes. Le rendu API semble presque identique dans les deux bibliothèques, mais la configuration, non.
Si votre app est gérée par Expo, utilisez expo-linear-gradient. Si votre app est en React Native bare, utilisez react-native-linear-gradient. N'essayez pas de brouiller ces lignes sans savoir exactement pourquoi vous le faites.

Configuration Expo
Expo est la voie la plus simple. L'installation est directe, la correspondance des versions est gérée pour vous et vous n'avez pas à vous soucier du linking natif.
Installez-le comme ceci :
bunx expo install expo-linear-gradient
Utilisez-le comme ceci :
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
export default function App() {
return (
<LinearGradient
colors={['#0f172a', '#1d4ed8']}
style={styles.container}
>
<Text style={styles.text}>Hello gradient</Text>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 24,
fontWeight: '700',
},
});
Expo est le bon choix quand vous voulez une mise en place rapide, des valeurs par défaut raisonnables et moins de cas limites natifs. C'est aussi pourquoi les équipes qui explorent des workflows Expo avancés comparent souvent Capgo et Expo EAS pour les live updates lorsque l'approche managée ne répond plus aux besoins de l'application.
Configuration Bare React Native
Bare React Native vous donne un accès direct aux modules natifs, mais vous devez gérer la complexité.
Installez le package :
bun add react-native-linear-gradient
Pour iOS, installez les pods :
cd ios && pod install
Utilisation de base :
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
export default function App() {
return (
<LinearGradient
colors={['#111827', '#7c3aed']}
style={styles.container}
>
<Text style={styles.text}>Hello gradient</Text>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 24,
fontWeight: '700',
},
});
Là où les projets bare cassent généralement
L’élément manquant dans la plupart des tutoriels est le test et la configuration native. Selon ce résumé de discussion sur Stack Overflow, 68 % des threads Stack Overflow sur ce sujet entre 2024 et 2025 concernent des échecs de modules natifs dans des configurations React Native pures, et la même source note des problèmes récurrents avec le mocking Jest et les conflits CocoaPods sur iOS.
Si vous utilisez Jest dans une app bare, ajoutez le mock explicitement :
// jest.setup.js
import mockRNLinearGradient from 'react-native-linear-gradient/jest/linear-gradient-mock';
jest.mock('react-native-linear-gradient', () => mockRNLinearGradient);
Et référencez ce fichier de configuration dans votre config Jest :
module.exports = {
preset: 'react-native',
setupFiles: ['<rootDir>/jest.setup.js'],
};
React Native bare fonctionne bien pour les dégradés. Il ne pardonne simplement pas une configuration incomplète. La plupart des échecs ne sont pas des bugs visuels. Ce sont des problèmes de linking, de pods ou d’environnement de test.
Voici le tableau de décision pratique :
| Type de projet | Bibliothèque | Le plus adapté |
|---|---|---|
| Application gérée par Expo | expo-linear-gradient |
Chemin le plus rapide, configuration minimale |
| Application React Native bare | react-native-linear-gradient |
Contrôle natif complet |
| Application bare avec Jest | react-native-linear-gradient + mock |
Nécessaire pour garder les tests stables |
Techniques de gradient essentielles pour l'UI
Une approche courante consiste à réutiliser un petit ensemble de motifs de dégradés. Fonds. Boutons. Titres. Si ces trois sont solides, vous pouvez les réutiliser sur de nombreux écrans.

Un modèle mental utile est le suivant :
colorscontrôle la palettestartetendcontrôle la directionlocationscontrôle l'endroit où se font les transitions
Si votre splash screen ou votre écran d'onboarding utilise un dégradé, il s'accorde naturellement avec les patterns de séquence de démarrage décrits dans ce Guide du splash screen React Native.
Gradients de fond plein écran
C'est le pattern le plus simple et le plus réutilisable.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
// For bare RN, switch to:
// import LinearGradient from 'react-native-linear-gradient';
export default function WelcomeScreen() {
return (
<LinearGradient
colors={['#0f172a', '#1e293b', '#2563eb']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.container}
>
<View style={styles.content}>
<Text style={styles.title}>Welcome back</Text>
<Text style={styles.subtitle}>Your workspace is ready.</Text>
</View>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 24,
},
title: {
color: '#fff',
fontSize: 32,
fontWeight: '800',
marginBottom: 8,
},
subtitle: {
color: 'rgba(255,255,255,0.8)',
fontSize: 16,
},
});
Un dégradé diagonal paraît souvent plus dynamique qu'un dégradé vertical par défaut. C'est pourquoi start={{ x: 0, y: 0 }} et end={{ x: 1, y: 1 }} sont un bon choix par défaut quand l'écran est surtout décoratif.
Ne choisissez pas vos couleurs de manière isolée. Testez-les avec du vrai texte, des icônes et des styles de barre d'état. Une palette qui rend bien dans Figma peut échouer instantanément dès que du contenu est posé dessus.
Boutons en gradient qui se comportent comme des boutons
L'erreur classique consiste à appliquer le comportement tactile directement sur le dégradé en oubliant l'état désactivé, le feedback au toucher ou la cohérence du padding. Gardez le bouton sémantique et laissez le dégradé servir de couche visuelle.
import React from 'react';
import {
Pressable,
StyleSheet,
Text,
ViewStyle,
StyleProp,
} from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
type Props = {
title: string;
onPress: () => void;
disabled?: boolean;
style?: StyleProp<ViewStyle>;
};
export function GradientButton({
title,
onPress,
disabled = false,
style,
}: Props) {
return (
<Pressable onPress={onPress} disabled={disabled} style={style}>
{({ pressed }) => (
<LinearGradient
colors={
disabled
? ['#94a3b8', '#94a3b8']
: pressed
? ['#7c3aed', '#2563eb']
: ['#8b5cf6', '#3b82f6']
}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.button}
>
<Text style={styles.label}>{title}</Text>
</LinearGradient>
)}
</Pressable>
);
}
const styles = StyleSheet.create({
button: {
minHeight: 52,
borderRadius: 14,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 20,
},
label: {
color: '#fff',
fontSize: 16,
fontWeight: '700',
},
});
Pour les boutons, un dégradé horizontal est souvent plus lisible qu'un dégradé diagonal. Il garde le libellé stable et évite de donner au bouton une impression d'inclinaison.
Texte en gradient avec un masque
C'est le motif le plus flashy de la série, et il est très utile quand vous le gardez sobre. Les titres hero, les bannières d'upgrade et les titres d'état vide sont de bons candidats. Le texte de paragraphe, non.
Il vous faudra @react-native-masked-view/masked-view.
bun add @react-native-masked-view/masked-view
Ensuite, créez le masque de texte :
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MaskedView from '@react-native-masked-view/masked-view';
import { LinearGradient } from 'expo-linear-gradient';
export default function GradientHeadline() {
return (
<View style={styles.container}>
<MaskedView
maskElement={
<View style={styles.maskWrapper}>
<Text style={styles.title}>Premium analytics</Text>
</View>
}
>
<LinearGradient
colors={['#22c55e', '#06b6d4', '#3b82f6']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
locations={[0, 0.5, 1]}
>
<Text style={[styles.title, styles.hiddenText]}>Premium analytics</Text>
</LinearGradient>
</MaskedView>
</View>
);
}
const styles = StyleSheet.create({
container: {
padding: 24,
},
maskWrapper: {
backgroundColor: 'transparent',
},
title: {
fontSize: 34,
fontWeight: '800',
letterSpacing: -1,
},
hiddenText: {
opacity: 0,
},
});
locations importe le plus quand vous voulez qu'une couleur occupe plus d'espace visuel qu'une autre. Si le mélange paraît brouillon, réduisez d'abord le nombre de couleurs. Cela corrige généralement le design plus vite que de peaufiner chaque stop.
Donner vie aux gradients avec des animations
Les dégradés statiques apportent de la finition. Les dégradés animés apportent du feedback.
L'usage le plus pratique n'est pas un arrière-plan tape-à-l'œil, mais un shimmer loader. Cet effet indique aux utilisateurs que l'app est active, que les données arrivent et que la mise en page qu'ils voient est voulue, pas cassée.

Un composant shimmer complète aussi d'autres motifs d'animation. Si votre app utilise déjà des icônes ou des loaders animés, ceci Guide Lottie dans React Native est utile pour décider quand un shimmer en dégradé suffit et quand un asset d'animation plus riche est plus pertinent.
Un shimmer loader au rendu natif
La version la plus simple et fiable utilise react-native-reanimated pour déplacer une bande de dégradé sur un placeholder clippé.
Installez Reanimated si ce n'est pas déjà fait dans votre app, puis créez un wrapper avec overflow: 'hidden'. À l'intérieur, animez une couche de dégradé de gauche à droite.
import React, { useEffect } from 'react';
import { StyleSheet, View, ViewStyle, StyleProp } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import Animated, {
useAnimatedStyle,
useSharedValue,
withRepeat,
withTiming,
Easing,
} from 'react-native-reanimated';
const AnimatedView = Animated.createAnimatedComponent(View);
type Props = {
width?: number | string;
height?: number;
borderRadius?: number;
style?: StyleProp<ViewStyle>;
};
export function ShimmerPlaceholder({
width = '100%',
height = 16,
borderRadius = 8,
style,
}: Props) {
const translateX = useSharedValue(-220);
useEffect(() => {
translateX.value = withRepeat(
withTiming(220, {
duration: 1200,
easing: Easing.linear,
}),
-1,
false
);
}, [translateX]);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
return (
<View
style={[
styles.container,
{ width, height, borderRadius },
style,
]}
>
<AnimatedView style={[styles.shimmer, animatedStyle]}>
<LinearGradient
colors={['rgba(255,255,255,0)', 'rgba(255,255,255,0.35)', 'rgba(255,255,255,0)']}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
style={styles.gradient}
/>
</AnimatedView>
</View>
);
}
const styles = StyleSheet.create({
container: {
overflow: 'hidden',
backgroundColor: '#e5e7eb',
},
shimmer: {
...StyleSheet.absoluteFillObject,
width: 220,
},
gradient: {
flex: 1,
},
});
Ce qui permet cela, c'est que vous n'essayez pas d'animer la définition du dégradé elle-même. Vous animez une couche de dégradé sur un placeholder statique. C'est plus simple, plus facile à comprendre et généralement plus stable sur tous les appareils.
Voici un aperçu visuel de l'effet en pratique :
Le composant animé
Quelques notes d'implémentation importantes :
- Utilisez le clipping : Le parent nécessite
overflow: 'hidden', sinon le shimmer débordera des coins arrondis. - Gardez la bande étroite : Une couche animée plus petite est plus facile à ajuster qu’en animant toute la surface.
- Faites correspondre la couleur de base à l’écran : Les skeleton loaders doivent s’adapter à la mise en page environnante, sans ressembler à un widget isolé.
Les dégradés animés fonctionnent le mieux quand l’utilisateur ne les remarque presque pas. Si l’effet shimmer devient l’élément le plus visible de l’écran, c’est qu’il en fait trop.
Performance, accessibilité et spécificités des plateformes
Une fois que les dégradés quittent les écrans de démo pour passer en production, les enjeux changent. Le code paraît toujours simple, mais le comportement de rendu, la lisibilité et la cohérence entre plateformes deviennent plus importants que l’effet initial.
Si vous cherchez à améliorer la réactivité de votre application de manière globale, ce guide d'optimisation des performances d'applications mobiles suit la même logique : réduire le travail inutile, mesurer sur de vrais appareils et optimiser les surfaces les plus vues par les utilisateurs.
Checklist de performance
Les dégradés natifs sont généralement efficaces, mais ils peuvent tout de même être mal utilisés.
- Privilégiez les dégradés aux grandes images décoratives : Ils sont souvent plus simples à déployer et plus faciles à adapter à différentes tailles d'écran.
- Évitez d'empiler de nombreuses couches plein écran : Un dégradé d'arrière-plan suffit. Plusieurs dégradés translucides superposés avec du flou et des animations lourdes peuvent coûter cher en ressources.
- Mémoïsez vos composants réutilisables : Si une carte avec dégradé est utilisée dans une liste, gardez les props stables et évitez de la re-rendre pour un état parent sans rapport.
Une bonne règle est de garder les dégradés structurels, sans excès. Utilisez-les pour définir des surfaces, pas pour chaque ligne d'un flux dense.
Checklist d'accessibilité
Les dégradés nuisent rapidement à la lisibilité, car le contraste varie sur la surface.
- Testez le texte sur la zone la plus claire : Si le texte blanc ne fonctionne que sur la partie sombre du dégradé, il ne convient pas.
- Ajoutez un scrim si nécessaire : Un léger voile sombre entre l’arrière-plan et le texte est souvent préférable à un changement complet de la palette.
- Réservez le texte en dégradé aux grandes mises en page : C’est efficace sur les titres. C’est un mauvais choix pour les petits libellés, les textes d’aide ou tout élément essentiel à l’accomplissement d’une tâche.
Vérifiez le point le moins favorable du dégradé, pas le plus joli.
Checklist des particularités de plateforme
iOS et Android affichent généralement le même dégradé de manière très proche, mais pas toujours parfaitement identique.
| Problème | Ce qui aide généralement |
|---|---|
| Le dégradé diffère selon les plateformes | Utilisez moins de couleurs et un contraste plus net entre les stops |
| Les coins arrondis ne rognent pas le dégradé | Placez overflow: 'hidden' sur le conteneur |
| Le gradient ne s'affiche pas du tout | Vérifiez la largeur, la hauteur ou flex: 1 d'abord |
Surveillez aussi votre barre de statut et la gestion de la safe area. Un gradient qui semble équilibré sur le simulateur peut paraître trop haut sur un appareil avec une encoche si le contenu et l'arrière-plan ne tiennent pas compte de cet espace supplémentaire.
Dépannage et bonnes pratiques finales
Voici la version courte que je garderais dans une note de projet.
- Adaptez la bibliothèque à votre workflow :
expo-linear-gradientpour les apps gérées avec Expo,react-native-linear-gradientpour le React Native bare. - Utilisez les gradients à bon escient : Les arrière-plans, les CTA, les overlays et le texte hero sont de bons cas d'usage.
- Contrôlez la direction intentionnellement : Horizontal pour les boutons, en diagonale pour les fonds décoratifs, masqué uniquement pour les grands textes.
- Concevez pour le contenu, pas pour les états vides : Testez avec du contenu réel, des icônes et le rendu de la barre d'état.
- Traitez le setup bare comme un setup natif : Les Pods, le linking et les mocks Jest ne sont pas des détails optionnels.
Trois erreurs courantes reviennent régulièrement.
Le gradient ne s'affiche pas
Cause : le composant n'a pas de taille visible.
Correction : donnez-lui flex: 1, une hauteur explicite, ou un parent avec des dimensions. Un dégradé sans boîte de mise en page ne s'affichera pas de manière significative.
Le build iOS échoue après l'installation
Cause : les pods n'ont pas été installés ou le graphe de dépendances natives est désynchronisé.
Fix : run pod install dans ios, nettoyez le dossier de build si nécessaire, puis recompilez l'app. Dans les projets bare, l'installation des packages seule ne suffit généralement pas.
Les tests échouent avec des erreurs de module natif
Cause : Jest tente de charger le module natif réel.
Fix : mock react-native-linear-gradient par react-native-linear-gradient/jest/linear-gradient-mock dans votre fichier de configuration Jest.
Si vous ne devez retenir qu'une chose de ce guide, c'est celle-ci : le gradient en lui-même est simple. L'effort principal réside dans la mise en place d'une configuration prête pour la production. Une fois que vous avez choisi la bonne bibliothèque pour l'architecture de votre app, tout le reste devient beaucoup plus prévisible.
Si votre équipe déploie des apps mobiles hybrides et veut pousser des mises à jour de JavaScript, CSS, de textes, de config et d'assets sans attendre la validation des stores, Capgo vaut le détour. Il offre aux équipes CapacitorJS et Electron des live updates contrôlés, des canaux de déploiement, une protection contre les rollback et une visibilité sur les releases, sans transformer votre processus de déploiement en boîte noire.