Sheet est un composant d'interface qui apparaît en bas de l'écran par-dessus le contenu principal et fournit des actions ou informations supplémentaires. Bottom Sheet est le type le plus courant, défini dans les directives de Material Design 3 (Google, 2024). Contrairement aux fenêtres de dialogue, un Sheet ne bloque pas complètement l'interaction avec l'arrière-plan et prend en charge les états collapsed et expanded. Comprendre les types et le comportement de Sheet est nécessaire pour construire une navigation pratique dans les applications mobiles.
Points clés
Sheet est un composant d'interface de niveau superficiel qui glisse du bas de l'écran et affiche du contenu ou des actions supplémentaires sans éloigner l'utilisateur de l'écran actuel. Contrairement aux transitions plein écran, un Sheet préserve le contexte : l'utilisateur voit l'écran d'arrière-plan et comprend d'où le Sheet est apparu.
L'architecture d'un Sheet est basée sur un conteneur à hauteur réglable. Dans son état minimal (collapsed), seule une partie du contenu est visible — généralement un titre ou un petit panneau. L'utilisateur peut faire glisser le Sheet vers le haut pour le développer (expanded) ou le balayer vers le bas pour le fermer. Ce comportement rappelle une feuille de papier physique glissée sous une pile — d'où son nom.
Google dans les directives Material Design 3 (2024) met en évidence deux scénarios clés d'utilisation de Sheet : afficher des actions supplémentaires qui ne tiennent pas dans la barre d'outils principale, et montrer des formulaires ou des informations détaillées sans naviguer vers un écran séparé. Sur iOS, Apple a ajouté la prise en charge système de Sheet à partir d'iOS 15 via UISheetPresentationController, confirmant l'universalité du modèle.
Material Design définit trois types de Bottom Sheet, chacun avec son propre comportement et domaine d'application. Choisir le bon type affecte directement l'expérience utilisateur et la conformité aux directives de la plateforme.
Bottom Sheet standard est un composant non modal : l'utilisateur peut interagir avec l'écran d'arrière-plan sans fermer le Sheet. Par exemple, en naviguant dans une liste de produits en arrière-plan, l'utilisateur voit des filtres dans un Bottom Sheet et peut les modifier sans fermer le panneau. Le Sheet ajuste sa hauteur au contenu — de 30 % à 90 % de l'écran.
Le Bottom Sheet standard ne bloque pas l'arrière-plan et permet l'interaction avec le contenu principal. C'est la principale différence avec le Sheet modal, qui nécessite une action obligatoire pour continuer. Utilisez un Sheet standard lorsque les informations supplémentaires ne sont pas critiques pour le scénario principal.
Bottom Sheet modal bloque l'interaction avec l'écran d'arrière-plan jusqu'à ce que l'utilisateur effectue une action dans le Sheet. Ce Sheet est toujours affiché dans l'état expanded et nécessite une fermeture explicite — via un bouton, une action ou un balayage vers le bas. Material Design recommande le Sheet modal pour les formulaires de connexion, les confirmations et les paramètres critiques.
Sur Android, le Bottom Sheet modal est implémenté via BottomSheetDialogFragment, qui bloque automatiquement l'arrière-plan. Sur iOS, un comportement similaire est fourni par la variante modale de UISheetPresentationController avec le paramètre .mediumDetent. Le Sheet modal ne doit être utilisé que lorsque le contexte nécessite l'attention de l'utilisateur.
Bottom Sheet étendu combine les propriétés du standard et du modal : il commence comme non modal dans l'état collapsed, mais lorsqu'il est glissé vers le haut, il devient modal. En pratique, cela signifie que l'utilisateur peut d'abord jeter un coup d'œil au contenu, puis décider — développer le Sheet pour une étude détaillée ou le fermer.
Ce modèle est particulièrement populaire dans les cartes et navigateurs, où le panneau inférieur affiche des informations brèves sur un point d'itinéraire, et lorsqu'on le balaye vers le haut, il se développe avec des détails. Google Maps utilise exactement ce Sheet étendu pour afficher des informations sur les lieux et les itinéraires.
| Type de Sheet | Blocage arrière-plan | État initial | Exemple |
|---|---|---|---|
| Standard | Non | Collapsed | Filtres dans le catalogue |
| Modal | Oui | Expanded | Formulaire de connexion |
| Étendu | Partiel | Collapsed | Carte de lieu |
Android SDK fournit plusieurs API pour implémenter Bottom Sheet, de l'approche classique basée sur View au moderne Jetpack Compose. La bibliothèque Material Components pour Android inclut des implémentations prêtes de BottomSheetDialogFragment et BottomSheetBehavior.
BottomSheetBehavior est une classe de Material Components qui s'attache à n'importe quelle View et contrôle sa position à l'écran. Le développeur définit trois états : STATE_COLLAPSED, STATE_EXPANDED et STATE_HIDDEN. Behavior gère automatiquement les gestes de glissement et l'animation.
val sheet = findViewById<View>(R.id.bottom_sheet)
val behavior = BottomSheetBehavior.from(sheet)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
behavior.peekHeight = 200
Jetpack Compose fournit une API plus déclarative via le composant ModalBottomSheet de Material 3. Contrairement à l'approche basée sur View, dans Compose, le Bottom Sheet est une fonction composable qui accepte l'état et le contenu. Le Sheet anime automatiquement l'apparition, la disparition et les changements de hauteur lors du glissement.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterSheet(onDismiss: () -> Unit) {
ModalBottomSheet(onDismissRequest = onDismiss) {
Text("Filtres")
Button(onClick = onDismiss) { Text("Appliquer") }
}
}
BottomSheetDialogFragment est un DialogFragment spécialisé qui s'affiche comme Bottom Sheet. Il gère automatiquement la modalité, le cycle de vie et les changements de configuration. Le développeur n'a qu'à surcharger onCreateView et retourner la mise en page du Sheet. Selon la documentation Google (Android Developers, 2024), BottomSheetDialogFragment est l'approche recommandée pour les Bottom Sheets modaux dans Android classique.
Apple a introduit la prise en charge système de Sheet à partir d'iOS 15 via UISheetPresentationController. Avant cela, les développeurs implémentaient Bottom Sheet manuellement avec des transitions personnalisées ou des bibliothèques tierces. Le Sheet natif d'Apple prend en charge les detents — des niveaux d'expansion prédéfinis.
UISheetPresentationController est un contrôleur de présentation intégré qui affiche un View Controller comme Sheet. Le développeur spécifie un tableau de detents — des valeurs de hauteur auxquelles le Sheet peut s'arrêter. iOS 16 a ajouté des detents personnalisés avec une hauteur arbitraire. Apple recommande d'utiliser les detents medium (.medium) et large (.large) comme principaux.
let viewController = MySheetViewController()
if let sheet = viewController.sheetPresentationController {
sheet.detents = [.medium, .large]
sheet.prefersGrabberVisible = true
sheet.preferredCornerRadius = 16
}
present(viewController, animated: true)
SwiftUI fournit le modificateur .sheet, qui lie l'affichage du Sheet à un état. Lorsqu'une variable published devient true, SwiftUI affiche automatiquement le Sheet. SwiftUI prend également en charge les detents via le modificateur .presentationDetents, ajouté dans iOS 16.
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Afficher Sheet") { showSheet = true }
.sheet(isPresented: $showSheet) {
FilterView()
.presentationDetents([.medium, .large])
}
}
}
Les frameworks multiplateformes prennent également en charge Bottom Sheet, en adaptant le comportement à la plateforme cible. Flutter et React Native fournissent des implémentations intégrées et personnalisées avec différents degrés de flexibilité.
Flutter SDK contient deux méthodes pour afficher Bottom Sheet : showBottomSheet (standard) et showModalBottomSheet (modal). Material Design dans Flutter suit les mêmes principes que dans Android — le Sheet apparaît par le bas, prend en charge le glissement et a une hauteur réglable. Pour un comportement étendu avec des detents, on utilise DraggableScrollableSheet.
Scaffold.of(context).showBottomSheet((context) {
return Container(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text("Contenu Sheet"),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("Fermer")
)
]
)
);
})
React Native n'a pas de composant Bottom Sheet intégré dans son noyau, donc les développeurs utilisent des bibliothèques tierces. La plus populaire est @gorhom/bottom-sheet (plus de 7 000 étoiles sur GitHub, 2024). Elle fournit un Bottom Sheet piloté par les gestes avec prise en charge des snap points, des animations et des en-têtes fixes. La bibliothèque est construite sur Reanimated 2 et Gesture Handler pour des performances à 60 FPS.
L'utilisation correcte de Bottom Sheet nécessite le respect des directives de la plateforme et la compréhension des scénarios dans lesquels un Sheet est approprié. Passons en revue les principales recommandations et les erreurs courantes lors de la conception de Sheets.
Bottom Sheet est optimal pour les actions qui sont complémentaires au contenu principal de l'écran. Filtres, tri, sélection d'options, informations brèves sur un élément — des scénarios typiques. Material Design recommande d'utiliser Bottom Sheet pour les outils qui ne doivent pas occuper tout l'écran mais nécessitent plus d'espace qu'un Action Sheet ou un Popup Menu.
N'utilisez pas Bottom Sheet pour les avertissements critiques ou les erreurs — les fenêtres de dialogue sont plus appropriées. Évitez les Sheets avec un grand nombre de champs de saisie nécessitant un défilement : l'utilisateur a du mal à atteindre le clavier et perd le contexte. Si un Sheet contient plus de sept éléments d'action, envisagez un écran séparé au lieu d'un Sheet.
Une erreur courante consiste à définir peekHeight (hauteur à l'état réduit) à plus de 40 % de l'écran. L'utilisateur ne sait pas s'il voit le Sheet en entier ou s'il peut être développé. Material Design recommande peekHeight entre 15 et 30 % de la hauteur de l'écran pour laisser une partie notable du contenu cachée et motiver le glissement.
Sur iOS, les utilisateurs s'attendent à pouvoir fermer un Sheet en balayant vers le bas depuis n'importe quelle position. Si vous désactivez ce geste (via UISheetPresentationController.prefersEdgeAttachedInCompactHeight), l'utilisateur éprouve de la frustration en essayant de fermer le Sheet de manière habituelle. Les Règles d'Interface Humaine d'Apple (2024) soulignent que le balayage pour fermer est une attente fondamentale des utilisateurs iOS.
Questions fréquentes
Bottom Sheet ne bloque pas complètement l'arrière-plan et prend en charge le glissement, tandis qu'une fenêtre de dialogue est modale et nécessite une action obligatoire. Bottom Sheet est mieux adapté aux options complémentaires, la dialogue pour les confirmations critiques.
Oui, mais il faut configurer adjustResize ou adjustPan dans le manifeste Android. Sur iOS, le clavier soulève automatiquement le Sheet. Flutter et React Native nécessitent un traitement manuel via MediaQuery pour un positionnement correct.
Il est recommandé de ne pas dépasser 5 à 7 éléments dans un Sheet standard. Si le contenu est plus volumineux, utilisez le défilement ou une division en catégories. Material Design conseille de ne pas dépasser 90 % de la hauteur de l'écran à l'état expanded.
Pour un Sheet modal, définissez setCancelable(true) sur Android ou isModalInPresentation = false sur iOS. Dans Jetpack Compose, onDismissRequest gère automatiquement le tap sur l'arrière-plan. Dans SwiftUI, le balayage vers le bas est le comportement par défaut.
Oui, toutes les implémentations natives prennent en charge VoiceOver et TalkBack. Assurez-vous que FocusManager déplace correctement le focus vers le Sheet lors de son ouverture et le ramène lors de sa fermeture. Les implémentations personnalisées nécessitent une configuration manuelle de l'accessibilité.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi