Mises en page Shiny : fluidPage, sidebarLayout et la grille à 12 colonnes

Agencez vos entrées et vos sorties sur la page — l’enveloppe de page, la division en panneau latéral, la grille, les onglets et la navigation multi-pages.

Programming
Shiny

Tous les conteneurs de mise en page Shiny au même endroit : fluidPage et titlePanel, sidebarLayout avec sidebarPanel et mainPanel, la grille fluidRow/column à 12 colonnes, tabsetPanel et navlistPanel, navbarPage pour les applications multi-pages, et wellPanel. Pour chacun, le code, ce qu’il agence, et quand y recourir — plus comment les largeurs de colonnes totalisent 12 et comment imbriquer les mises en page.

Date de publication

28 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • Chaque application commence par une fonction de page : enveloppez tout le ui dans fluidPage() (responsive, le défaut) et donnez-lui un titlePanel().
  • sidebarLayout() est la division classique : les contrôles dans sidebarPanel() à gauche, les résultats dans mainPanel() à droite — la mise en page qu’utilisent la plupart des applications de données.
  • La grille, c’est fluidRow() + column(), et les largeurs totalisent 12. Une ligne fait 12 unités de large ; column(4, …) + column(8, …) la remplit. Utilisez offset = pour pousser une colonne vers la droite.
  • tabsetPanel() + tabPanel() créent des onglets ; navbarPage() crée une application multi-pages avec une barre de navigation en haut — recourez aux onglets pour grouper des vues, à une barre de navigation pour séparer des sections entières.
  • wellPanel() est un encadré gris qui groupe visuellement des contrôles. Les conteneurs de mise en page s’imbriquent librement — des colonnes dans des lignes, des onglets dans un mainPanel, un wellPanel dans une colonne.

Introduction

Les entrées collectent des choix et les sorties affichent des résultats — les mises en page décident où ils se placent sur la page. Un conteneur de mise en page est une fonction dans laquelle vous enveloppez vos widgets et vos affichages ; il les agence en lignes, colonnes, panneaux latéraux ou onglets. Réussissez la mise en page et une application se lit d’elle-même ; ratez-la et une application puissante paraît à l’étroit ou chaotique.

C’est la référence à laquelle vous revenez. Chaque conteneur de mise en page que vous utiliserez est ici, groupé par la tâche qu’il accomplit, et pour chacun vous obtenez trois choses : le code, ce qu’il agence, et quand l’utiliser. Vous savez déjà déclarer les entrées et les sorties ; ici vous apprenez à les placer — de l’enveloppe de page jusqu’à une grille à 12 colonnes.

NoteCopiez n’importe quel bloc et exécutez-le en local

Le code de cette page n’est pas exécuté ici — une application Shiny a besoin d’une session R active, elle ne peut donc pas tourner dans une page web statique. Copiez n’importe quel bloc dans un fichier app.R et exécutez-le en local avec shiny::runApp() (ou cliquez sur Run App dans RStudio). Chaque exemple montre une mise en page isolée ; remplissez-la avec vos propres entrées et sorties.

Le conteneur de page

Le ui de chaque application est enveloppé dans une unique fonction de page — le conteneur le plus externe. fluidPage() est celle que vous utiliserez presque toujours : elle construit une page responsive qui s’adapte à la largeur du navigateur et se réorganise sur les petits écrans. Tout le reste se place à l’intérieur.

titlePanel() place un titre en haut de la page (et définit le titre de l’onglet du navigateur). C’est la première chose conventionnelle à mettre à l’intérieur de fluidPage().

library(shiny)

ui <- fluidPage(
  titlePanel("My App"),
  # ...all your layout, inputs, and outputs go here...
)

Tout dans cette leçon vit à l’intérieur d’une fonction de page. Une règle : une fonction de page enveloppe tout le ui une seule fois — vous n’imbriquez pas un fluidPage() dans un autre fluidPage() (voir Problèmes fréquents).

La mise en page à panneau latéral

sidebarLayout() est l’agencement le plus courant pour une application de données : un sidebarPanel() étroit de contrôles à gauche, un large mainPanel() de résultats à droite. Il renvoie une mise en page complète en deux parties, vous la déposez donc directement dans fluidPage(). Utilisez-la chaque fois que l’utilisateur règle des options qui pilotent un unique affichage principal — la forme par défaut de presque toute application d’analyse.

ui <- fluidPage(
  titlePanel("Histogram explorer"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
    ),
    mainPanel(
      plotOutput("hist")
    )
  )
)

Par défaut le panneau latéral prend 4 des 12 unités de la grille et le panneau principal en prend 8. Changez la répartition avec l’argument width sur chaque panneau — sidebarPanel(width = 3, …) et mainPanel(width = 9, …) pour un panneau latéral plus étroit. Placez le panneau latéral à droite avec sidebarLayout(…, position = "right").

La grille à 12 colonnes

Quand vous avez besoin de plus qu’une division panneau-latéral-et-principal, construisez votre propre agencement avec la grille. Une page fait 12 unités de large. fluidRow() crée une ligne horizontale ; column(width, …) en découpe une partie — et les largeurs d’une ligne devraient totaliser 12. C’est le fondement sur lequel toute autre mise en page est bâtie.

column(6, …) + column(6, …) crée deux moitiés égales ; column(4, …) + column(8, …) crée une division un tiers / deux tiers. Utilisez la grille quand vous voulez un agencement sur mesure — plusieurs panneaux côte à côte, un bandeau d’en-tête au-dessus d’un corps à deux colonnes, une galerie de cellules égales.

ui <- fluidPage(
  fluidRow(
    column(6, h3("Left half"),  plotOutput("a")),
    column(6, h3("Right half"), plotOutput("b"))
  )
)

offset = pousse une colonne vers la droite du nombre d’unités indiqué — pratique pour centrer. column(6, offset = 3, …) place une colonne demi-largeur au milieu (3 unités vides de chaque côté).

ui <- fluidPage(
  fluidRow(
    column(6, offset = 3, h3("Centred content"))
  )
)

Sur un écran étroit les colonnes s’empilent verticalement d’elles-mêmes — la grille est responsive, vous n’écrivez donc rien de plus pour le mobile.

Les mises en page s’imbriquent : une column() peut contenir sa propre fluidRow(), et une ligne peut contenir des colonnes qui contiennent chacune d’autres lignes. Gardez l’imbrication peu profonde, cependant — une grille profondément imbriquée est difficile à lire et à maintenir.

ui <- fluidPage(
  fluidRow(
    column(12, h2("Header"))          # full-width band
  ),
  fluidRow(
    column(3, h4("Controls")),        # narrow sidebar...
    column(9, plotOutput("plot"))     # ...wide content (3 + 9 = 12)
  )
)

Onglets

tabsetPanel() regroupe plusieurs vues en onglets, chaque vue dans un tabPanel(). Un seul onglet s’affiche à la fois, c’est donc la façon de faire tenir un graphique, un résumé et un tableau de données dans le même espace sans faire défiler par-delà les trois. Donnez un id à tabsetPanel() si le server a besoin de savoir quel onglet est ouvert.

tabsetPanel(
  tabPanel("Plot",    plotOutput("plot")),
  tabPanel("Summary", verbatimTextOutput("summary")),
  tabPanel("Table",   tableOutput("table"))
)

Les onglets sont couramment placés à l’intérieur d’un mainPanel() — les contrôles restent en place dans le panneau latéral pendant que l’utilisateur passe d’une vue de résultats à l’autre.

navlistPanel() reprend la même idée avec les étiquettes d’onglets empilées verticalement sur le côté au lieu d’une ligne horizontale. Préférez-le quand vous avez beaucoup de sections ou de longues étiquettes qui ne tiendraient pas en haut.

navlistPanel(
  tabPanel("Overview", "..."),
  tabPanel("Details",  "..."),
  tabPanel("Settings", "...")
)

Grouper avec wellPanel

wellPanel() enveloppe son contenu dans un encadré gris en creux — un léger cadre visuel qui dit « ces éléments vont ensemble. » Il ne change pas la grille ; c’est purement un repère de groupement. Utilisez-le pour distinguer un bloc de contrôles liés du reste de la page.

wellPanel(
  h4("Filters"),
  selectInput("var", "Variable:", choices = names(mtcars)),
  sliderInput("n", "Rows:", min = 1, max = 32, value = 10)
)

sidebarPanel() dessine déjà cet encadré gris, vous avez donc rarement besoin de wellPanel() dans un panneau latéral — recourez-y pour grouper des contrôles qui vivent dans une simple column().

Pages à largeur fixe et pleine fenêtre

Deux alternatives à fluidPage() pour des besoins spécifiques :

  • fixedPage() plafonne le contenu à une largeur maximale fixe et le centre sur les écrans larges, au lieu de l’étirer d’un bord à l’autre. Utilisez-le quand une application paraît trop clairsemée étalée sur un moniteur ultra-large et que vous voulez une colonne contenue, façon document.
  • fillPage() fait remplir à son contenu toute la hauteur de la fenêtre du navigateur — utile pour un unique graphique ou une carte plein écran qui devrait occuper tout l’espace disponible plutôt que de s’inscrire dans le flux normal de la page.

Les deux sont des remplacements directs de fluidPage() en tête du ui ; fluidPage() reste le bon défaut pour la grande majorité des applications.

Quelle mise en page pour quelle tâche

Une recherche rapide. Le conteneur que vous choisissez découle de la façon dont vous voulez organiser la page.

Vous voulez… Utiliser Ce qu’il agence
L’enveloppe de page (responsive) fluidPage() tout le ui, s’adapte à la largeur
Un titre / en-tête de page titlePanel() un titre en haut
Contrôles à gauche, résultats à droite sidebarLayout() + sidebarPanel() / mainPanel() la division classique en deux parties
Un agencement côte à côte sur mesure fluidRow() + column() une ligne de grille de 12 unités
Pousser une colonne vers la droite column(width, offset = n, …) laisse n unités vides à gauche
Plusieurs vues dans un même espace tabsetPanel() + tabPanel() des onglets horizontaux
Beaucoup de sections / de longues étiquettes navlistPanel() des onglets verticaux sur le côté
Une application multi-pages navbarPage() + tabPanel() une barre de navigation en haut, une page par onglet
Grouper des pages de navbar dans un menu navbarMenu() un menu déroulant dans la barre de navigation
Grouper visuellement des contrôles wellPanel() un encadré de groupement gris
Une page centrée à largeur fixe fixedPage() plafonne la largeur du contenu
Une page pleine hauteur de fenêtre fillPage() remplit toute la fenêtre

Le motif est constant : une fonction de page enveloppe tout, sidebarLayout ou fluidRow/column agence le corps, et des onglets ou une barre de navigation ajoutent une seconde dimension quand un seul écran ne suffit pas.

Problèmes fréquents

Vos colonnes ne s’alignent pas — les largeurs ne totalisent pas 12. Une fluidRow() fait 12 unités de large. Si vous écrivez column(4, …) + column(4, …) (total 8), la ligne laisse 4 unités vides à droite ; column(6, …) + column(8, …) (total 14) déborde et la deuxième colonne passe à la ligne suivante. Faites en sorte que les largeurs de chaque ligne totalisent exactement 12 et la mise en page se met en place.

column() ne fait rien / génère une erreur hors d’une ligne. column() ne fonctionne qu’à l’intérieur d’une fluidRow() (ou d’un sidebarPanel/mainPanel, qui fournissent la ligne eux-mêmes). Un simple column(6, …) déposé directement dans fluidPage() n’a pas de grille pour se dimensionner. Enveloppez toujours les colonnes dans une fluidRow().

Imbriquer une fonction de page dans une autre fonction de page. Une fluidPage() (ou navbarPage, fixedPage) est le conteneur de premier niveau — elle enveloppe tout le ui une seule fois. Mettre une fluidPage() dans une column() ou une autre fluidPage() double le rembourrage de la page et casse la grille. À l’intérieur de la page, utilisez fluidRow(), sidebarLayout(), wellPanel() et div() pour agencer le contenu — jamais une seconde fonction de page.

Questions fréquentes

Chaque fluidRow() fait 12 unités de large, et chaque column(width, …) à l’intérieur réclame width de ces unités. Les largeurs d’une ligne devraient totaliser 12 — column(4, …) + column(8, …) remplit la ligne en une division un tiers / deux tiers. Les colonnes s’empilent verticalement sur les écrans étroits automatiquement, la grille est donc responsive sans code supplémentaire.

fluidPage() est l’enveloppe de page — le conteneur le plus externe qui contient tout le ui. sidebarLayout() est une mise en page à l’intérieur de cette page : elle divise le corps en un sidebarPanel() (contrôles) et un mainPanel() (résultats). Vous les utilisez ensemble — sidebarLayout() va à l’intérieur de fluidPage().

Utilisez tabsetPanel() avec un tabPanel() par vue : tabsetPanel(tabPanel("Plot", plotOutput("p")), tabPanel("Table", tableOutput("t"))). Un seul onglet s’affiche à la fois. Placez-le là où vous voulez que les onglets apparaissent — couramment à l’intérieur d’un mainPanel(). Pour des onglets verticaux sur le côté, utilisez navlistPanel() à la place.

Utilisez navbarPage() comme conteneur de premier niveau au lieu de fluidPage(). Chaque tabPanel() devient une page entière accessible depuis une barre de navigation en haut : navbarPage("My App", tabPanel("Home", …), tabPanel("About", …)). Regroupez des pages liées sous un menu déroulant avec navbarMenu(). Recourez à une barre de navigation quand l’application a des sections distinctes plutôt qu’un seul écran de résultats.

Passez l’argument width (en unités de grille, sur 12) à chaque panneau : sidebarPanel(width = 3, …) et mainPanel(width = 9, …) pour un panneau latéral plus étroit que le défaut 4/8. Déplacez le panneau latéral vers la droite avec sidebarLayout(…, position = "right").

Testez vos connaissances

Construisez un ui pour une application d’histogramme. Enveloppez-le dans fluidPage() avec un titlePanel(). Utilisez un sidebarLayout() où le panneau latéral contient un sliderInput("bins", …) et le panneau principal contient un tabsetPanel() avec deux onglets : un onglet Plot affichant plotOutput("hist") et un onglet Summary affichant verbatimTextOutput("stats").

Le squelette est fluidPage(titlePanel(…), sidebarLayout(sidebarPanel(…), mainPanel(…))). Le curseur va à l’intérieur de sidebarPanel(). À l’intérieur de mainPanel(), placez un tabsetPanel() avec deux appels tabPanel() — chacun prend une chaîne d’étiquette et la sortie à afficher.

ui <- fluidPage(
  titlePanel("Histogram explorer"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30)
    ),
    mainPanel(
      tabsetPanel(
        tabPanel("Plot",    plotOutput("hist")),
        tabPanel("Summary", verbatimTextOutput("stats"))
      )
    )
  )
)

sidebarLayout() crée la division contrôles-à-gauche / résultats-à-droite ; le tabsetPanel() à l’intérieur de mainPanel() permet à l’utilisateur de passer du graphique au résumé pendant que le curseur reste en place dans le panneau latéral.

Vous écrivez une ligne ainsi : fluidRow(column(5, …), column(5, …)). Que se passe-t-il ?

A. Les deux colonnes remplissent la ligne uniformément, chacune prenant la moitié. B. Les colonnes prennent 5 + 5 = 10 unités, laissant 2 unités vides à droite. C. Cela génère une erreur, car les largeurs de colonnes doivent toujours totaliser 12. D. La deuxième colonne passe à la ligne suivante.

B. Une fluidRow() fait 12 unités de large ; column(5, …) + column(5, …) en réclame 10, la ligne a donc 2 unités vides à droite et les colonnes ne sont pas centrées. Cela ne génère pas d’erreur (C) — le sous-remplissage est autorisé, ça paraît juste décalé. Le passage à la ligne (D) ne se produit que lorsque les largeurs dépassent 12. Pour deux moitiés égales, utilisez column(6, …) deux fois.

Conclusion

Vous disposez désormais de la boîte à outils de mise en page complète : l’enveloppe de page (fluidPage, avec fixedPage / fillPage pour des besoins de largeur fixe ou de pleine fenêtre), la classique sidebarLayout() avec sidebarPanel / mainPanel, la grille à 12 colonnes (fluidRow + column, les largeurs totalisant 12, offset pour décaler), les onglets (tabsetPanel / tabPanel, ou navlistPanel pour la verticale), la navigation multi-pages (navbarPage / navbarMenu), et wellPanel pour le groupement visuel. Ils s’imbriquent librement, et la grille est responsive par défaut — les colonnes s’empilent sur les petits écrans sans travail supplémentaire.

Avec les entrées, les sorties, et maintenant les mises en page en main, la dernière pièce du ui est de lui donner l’apparence que vous voulez — couleurs, polices et thèmes.

Leçons connexes

Cette page vous a-t-elle été utile ?

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Mises en page Shiny : fluidPage, sidebarLayout et la grille à
    12 colonnes},
  date = {2026-06-28},
  url = {https://www.datanovia.com/learn/programming/shiny/ui/layout-systems},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Mises en page Shiny : fluidPage, sidebarLayout et la grille à 12 colonnes.” 2026. June 28. https://www.datanovia.com/learn/programming/shiny/ui/layout-systems.