Séance 4 · 2 heures

Construire une mise en page responsive avec Flexbox et Grid

Organiser les éléments d’une page avec Flexbox et CSS Grid, puis adapter cette mise en page aux différentes dimensions d’écran grâce à une approche mobile first et aux media queries.

CSS 2Flexbox et GridMobile firstPrérequis : chapitre 3

Déroulé de la séance

18:00–18:10Rappel

Modèle de boîte et page mise en forme au chapitre 3.

18:10–18:45Flexbox

Axes, alignement, répartition et flexibilité.

18:45–19:20CSS Grid

Colonnes, zones nommées et combinaison avec Flexbox.

19:20–20:00Responsive

Mobile first, media queries, tests et corrections.

I

Organiser les éléments avec Flexbox

1

Comprendre le fonctionnement d’un conteneur flexible

a

Distinguer le flux normal et la mise en page flexible

flux normalempilementblocalignementdisposition

Dans le flux normal, les éléments de type bloc se placent généralement les uns sous les autres et occupent toute la largeur disponible. Les éléments en ligne s’insèrent dans le texte sans provoquer automatiquement de retour à la ligne. Flexbox modifie cette organisation en permettant au parent de contrôler la disposition, l’alignement et la répartition de ses enfants directs.

Exemple de code
<div class="informations">
  <article>Lieu</article>
  <article>Horaire</article>
  <article>Tarif</article>
</div>

/* Flux normal : les articles sont empilés. */
.informations article {
  padding: 1rem;
  border: 1px solid #cbd5e1;
}
b

Activer Flexbox avec display: flex

conteneurenfants directsflexboxdispositionactivation

La déclaration display: flex transforme un élément en conteneur flexible. Ses enfants directs deviennent alors des éléments flexibles et sont placés par défaut sur une même ligne. Les descendants plus profonds ne sont pas directement concernés : chaque niveau nécessitant une organisation flexible doit posséder son propre conteneur Flexbox.

Exemple de code
<div class="informations">
  <article>Lieu</article>
  <article>Horaire</article>
  <article>Tarif</article>
</div>

.informations {
  display: flex;
}
c

Identifier l’axe principal et l’axe secondaire

axe principalaxe secondairedirectionlignecolonne

Flexbox organise les éléments selon un axe principal et un axe secondaire. Avec flex-direction: row, l’axe principal est horizontal et l’axe secondaire vertical. Avec flex-direction: column, cette organisation est inversée. Comprendre ces axes est indispensable, car les propriétés d’alignement n’agissent pas toujours dans la même direction.

Exemple de code
.informations {
  display: flex;
  flex-direction: row;
}

/* L’axe principal devient vertical. */
.formulaire {
  display: flex;
  flex-direction: column;
}
2

Aligner et répartir les éléments

a

Répartir les éléments avec justify-content

répartitionaxe principalespacecentragealignement

La propriété justify-content répartit les éléments le long de l’axe principal. Elle peut les placer au début, au centre ou à la fin du conteneur, mais aussi distribuer l’espace disponible entre eux. Son effet dépend de la direction définie par flex-direction et suppose généralement qu’un espace libre existe.

Exemple de code
.navigation ul {
  display: flex;
  justify-content: space-between;
  list-style: none;
  margin: 0;
  padding: 0;
}
b

Aligner les éléments avec align-items et align-self

axe secondairealignementélémentconteneurexception

align-items contrôle l’alignement de tous les éléments flexibles sur l’axe secondaire. align-self permet ensuite de modifier individuellement l’alignement d’un élément particulier. Ces propriétés servent notamment à centrer verticalement des éléments de tailles différentes ou à distinguer un bouton au sein d’un groupe.

Exemple de code
.entete {
  display: flex;
  align-items: center;
  min-height: 100px;
}

.entete .bouton-inscription {
  align-self: flex-end;
}
c

Créer des espacements réguliers avec gap

espacementintervallerégularitélignescolonnes

La propriété gap définit un espace régulier entre les éléments d’un conteneur flexible sans ajouter de marge à ses extrémités. Elle évite de gérer séparément les marges de chaque enfant et simplifie la maintenance. Deux valeurs peuvent distinguer l’espace entre les lignes de celui entre les colonnes.

Exemple de code
.navigation ul {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.informations {
  display: flex;
  gap: 1rem 2rem;
}
3

Contrôler le comportement des éléments flexibles

a

Autoriser le retour à la ligne avec flex-wrap

retour à la lignedébordementadaptationlargeurenveloppement

Par défaut, Flexbox essaie de conserver tous les éléments sur une seule ligne, quitte à réduire leur largeur. flex-wrap: wrap les autorise à passer sur une nouvelle ligne lorsque l’espace devient insuffisant. Cette propriété convient notamment aux groupes de cartes, de boutons ou d’étiquettes dont le nombre peut varier.

Exemple de code
.informations {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.informations article {
  width: 250px;
}
b

Régler les dimensions avec les propriétés flex

dimension initialeagrandissementréductionespace disponibleflexibilité

flex-basis définit la dimension initiale d’un élément sur l’axe principal. flex-grow indique sa capacité à occuper l’espace restant et flex-shrink sa capacité à se réduire lorsque l’espace manque. La propriété raccourcie flex regroupe ces trois valeurs.

Exemple de code
.informations article {
  flex-basis: 220px;
  flex-grow: 1;
  flex-shrink: 1;
}

/* Écriture raccourcie équivalente. */
.informations article {
  flex: 1 1 220px;
}
c

Modifier ponctuellement l’ordre avec order

ordre visuelprioritésource HTMLaccessibilitéréorganisation

La propriété order modifie l’ordre visuel des éléments flexibles sans changer leur position dans le document HTML. Elle peut résoudre un besoin ponctuel de présentation, mais ne doit pas servir à corriger une structure HTML incohérente. La navigation au clavier et les technologies d’assistance continuent généralement de suivre l’ordre du code source.

Exemple de code
<div class="contenu">
  <main class="article">Contenu principal</main>
  <aside class="complement">Informations complémentaires</aside>
</div>

.contenu { display: flex; }
.article { order: 2; }
.complement { order: 1; }
1

Exercice — Organiser l’en-tête avec Flexbox

15 minutes · Individuel · Page du chapitre 3

Mission

Reprenez la page d’inscription mise en forme au chapitre 3 et réorganisez son en-tête et ses informations pratiques avec Flexbox.

Consignes

  1. Placez le titre et la navigation sur une même ligne.
  2. Répartissez l’espace disponible entre les deux zones.
  3. Alignez verticalement les liens et ajoutez un espacement avec gap.
  4. Autorisez le retour à la ligne lorsque la largeur devient insuffisante.
  5. Transformez les informations pratiques en rangée de cartes flexibles.
Livrable : un en-tête et une rangée de cartes utilisant display: flex, les propriétés d’alignement, gap et flex-wrap.
II

Construire une mise en page avec CSS Grid

1

Définir une grille

a

Activer la grille avec display: grid

grilleconteneurcelluleslignescolonnes

La déclaration display: grid transforme un élément en conteneur de grille. Ses enfants directs peuvent alors être organisés selon des lignes et des colonnes. Contrairement à Flexbox, Grid contrôle simultanément les deux dimensions et convient particulièrement à la structure générale d’une page ou à une collection régulière de cartes.

Exemple de code
<div class="page">
  <header>En-tête</header>
  <main>Contenu principal</main>
  <aside>Informations complémentaires</aside>
  <footer>Pied de page</footer>
</div>

.page {
  display: grid;
}
b

Créer des colonnes et des lignes avec les propriétés grid-template

colonneslignesgabaritdimensionstructure

grid-template-columns définit le nombre et la largeur des colonnes, tandis que grid-template-rows règle la hauteur des lignes. Les dimensions peuvent être exprimées en pixels, en unités relatives ou avec des valeurs automatiques. Le navigateur crée ensuite des cellules à l’intersection de ces lignes et colonnes.

Exemple de code
.page {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}
c

Utiliser les unités fr, repeat() et minmax()

fractionrépétitionminimummaximumadaptation

L’unité fr représente une fraction de l’espace disponible. repeat() évite de répéter plusieurs fois la même dimension et minmax() fixe une taille minimale et une taille maximale. Leur combinaison permet de créer une grille qui adapte automatiquement le nombre et la largeur des colonnes.

Exemple de code
.cartes {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(220px, 1fr)
  );
  gap: 1.5rem;
}
2

Positionner les éléments dans la grille

a

Définir les espaces avec gap

gouttièreespacementgrillelignecolonne

Dans une grille, gap définit l’espace séparant les lignes et les colonnes. Il crée des gouttières régulières sans modifier les dimensions internes des éléments. row-gap et column-gap peuvent être utilisés lorsque les espacements verticaux et horizontaux doivent être différents.

Exemple de code
.page {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 2rem;
}

.cartes {
  display: grid;
  row-gap: 1rem;
  column-gap: 1.5rem;
}
b

Étendre un élément avec grid-column et grid-row

positionnementétendueligne de grillecolonnefusion

grid-column et grid-row déterminent la position et l’étendue d’un élément dans la grille. Un contenu peut ainsi occuper plusieurs colonnes ou plusieurs lignes. Les nombres employés désignent les lignes qui délimitent les cellules, et non directement les colonnes elles-mêmes.

Exemple de code
.page {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 2rem;
}

.presentation,
.faq {
  grid-column: 1 / -1;
}

.programme { grid-column: 1 / 2; }
.inscription { grid-column: 2 / 3; }
c

Organiser la page avec grid-template-areas

zones nomméesgabaritlisibilitéplacementstructure

grid-template-areas permet de représenter la disposition de la page avec des noms explicites. Chaque élément reçoit ensuite une zone grâce à grid-area. Cette écriture rend les organisations complexes plus lisibles et facilite leur modification dans une media query.

Exemple de code
.page {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-areas:
    "entete entete"
    "programme formulaire"
    "faq faq";
  gap: 2rem;
}

.entete { grid-area: entete; }
.programme { grid-area: programme; }
.formulaire { grid-area: formulaire; }
.faq { grid-area: faq; }
3

Choisir entre Flexbox et Grid

a

Utiliser Flexbox pour organiser les éléments sur un axe

unidimensionnellignecolonnealignementdistribution

Flexbox convient lorsque les éléments doivent principalement être organisés sur une seule ligne ou une seule colonne. Il est adapté à une navigation, un groupe de boutons, un en-tête ou l’intérieur d’une carte. Il contrôle efficacement l’alignement et la répartition de contenus dont les dimensions peuvent varier.

Exemple de code
.navigation ul {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1.5rem;
}

.boutons {
  display: flex;
  gap: 1rem;
}
b

Utiliser Grid pour construire une organisation bidimensionnelle

bidimensionnellignescolonnesgabaritstructure générale

CSS Grid est préférable lorsque les lignes et les colonnes doivent être contrôlées simultanément. Il convient à l’organisation générale d’une page, à une galerie ou à une série de cartes devant rester alignées. Les éléments sont placés dans un gabarit commun plutôt que distribués uniquement selon un axe.

Exemple de code
.contenu-principal {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-template-areas:
    "presentation presentation"
    "programme inscription"
    "informations informations"
    "faq faq";
  gap: 2rem;
}
c

Combiner Flexbox et Grid dans une même page

combinaisongrille principalecomposantimbricationcomplémentarité

Flexbox et Grid ne sont pas concurrents : ils répondent à des besoins différents et peuvent être combinés. Grid peut organiser les grandes zones de la page, tandis que Flexbox gère l’alignement interne d’une navigation, d’une carte ou d’un formulaire. Chaque conteneur doit utiliser le système correspondant à sa fonction.

Exemple de code
/* Organisation générale. */
.contenu-principal {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 2rem;
}

/* Organisation interne d’une carte. */
.carte {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.carte a { margin-top: auto; }
2

Fil rouge — Construire la grille de la page

20 minutes · Binômes · Flexbox et Grid combinés

Mission

Organisez les grandes zones de la page d’inscription avec CSS Grid sans modifier sa structure HTML.

Consignes

  1. Placez la présentation sur toute la largeur.
  2. Installez le programme dans une colonne principale et le formulaire dans une colonne secondaire.
  3. Placez les informations pratiques et la FAQ sur toute la largeur.
  4. Utilisez des zones nommées avec grid-template-areas.
  5. Conservez Flexbox à l’intérieur de la navigation et des cartes.
Livrable : une mise en page sur deux colonnes combinant Grid pour la structure générale et Flexbox pour les composants.
III

Adapter la page aux différentes dimensions d’écran

1

Construire une interface flexible

a

Adopter une approche mobile first

mobile firststyle initialprogressionprioritéamélioration

L’approche mobile first consiste à écrire d’abord les styles destinés aux petits écrans, puis à enrichir progressivement la mise en page lorsque l’espace disponible augmente. Elle oblige à hiérarchiser les contenus essentiels et limite les règles correctives. Les media queries utilisant min-width ajoutent ensuite les dispositions adaptées aux écrans plus larges.

Exemple de code
/* Style initial : petit écran. */
.contenu-principal {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 768px) {
  .contenu-principal {
    grid-template-columns: 2fr 1fr;
    gap: 2rem;
  }
}
b

Utiliser des largeurs relatives et max-width

largeur relativelimitecentragefluiditélisibilité

Les largeurs exprimées en pourcentage s’adaptent à l’espace disponible, tandis que max-width empêche le contenu de devenir excessivement large. L’association d’une largeur fluide et d’une limite maximale produit une page lisible sur différents écrans. Les marges automatiques permettent ensuite de centrer le conteneur.

Exemple de code
.conteneur {
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
}

.formulaire {
  width: 100%;
  max-width: 600px;
}
c

Rendre les images et les médias adaptatifs

image fluidemédiadébordementproportionadaptation

Une image dont la largeur est supérieure à celle de son conteneur provoque un débordement horizontal. max-width: 100% limite sa largeur et height: auto conserve ses proportions. Une vidéo intégrée peut utiliser aspect-ratio afin de préserver son format lorsque sa largeur évolue.

Exemple de code
img,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

.video-responsive {
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
}
2

Modifier la mise en page avec les media queries

a

Écrire une media query avec @media

media queryconditionlargeurrègleadaptation

Une media query applique des règles CSS lorsque certaines conditions sont remplies. La condition min-width convient à une approche mobile first : les styles initiaux concernent les petits écrans et les règles supplémentaires apparaissent lorsque la largeur devient suffisante. Les règles générales restent actives tant qu’elles ne sont pas redéfinies.

Exemple de code
.navigation ul {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

@media (min-width: 768px) {
  .navigation ul {
    flex-direction: row;
    justify-content: flex-end;
    gap: 1.5rem;
  }
}
b

Choisir des points de rupture selon le contenu

point de rupturecontenuespace disponibletestcohérence

Un point de rupture doit correspondre au moment où le contenu ne tient plus correctement, et non obligatoirement à un modèle précis de téléphone ou de tablette. Il faut redimensionner progressivement la fenêtre et observer les débordements, les lignes trop longues ou les éléments trop serrés. La valeur retenue doit répondre à un problème concret.

Exemple de code
.cartes {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 640px) {
  .cartes { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .cartes { grid-template-columns: repeat(3, 1fr); }
}
c

Modifier la grille, la navigation et les espacements

réorganisationgrillenavigationespacementécran

Une media query peut modifier plusieurs dimensions de l’interface : nombre de colonnes, orientation de la navigation, largeur du conteneur ou espacements. Il est toutefois préférable de regrouper les changements liés au même point de rupture et de ne redéfinir que les propriétés nécessaires. La structure HTML doit rester identique.

Exemple de code
.page {
  display: grid;
  grid-template-areas:
    "entete"
    "programme"
    "formulaire"
    "faq";
  gap: 1rem;
  padding: 1rem;
}

@media (min-width: 900px) {
  .page {
    grid-template-columns: 2fr 1fr;
    grid-template-areas:
      "entete entete"
      "programme formulaire"
      "faq faq";
    gap: 2rem;
    padding: 2rem;
  }
}
3

Tester et finaliser la page responsive

a

Contrôler la page avec le mode responsive du navigateur

inspecteursimulationlargeurorientationtest

Le mode responsive des outils de développement permet de simuler différentes largeurs, hauteurs et orientations d’écran. Il ne faut pas se limiter aux modèles d’appareils proposés : déplacer librement la largeur révèle souvent les points où la mise en page devient instable. Cette simulation complète, mais ne remplace pas totalement, les tests sur des appareils réels.

Exemple de code
/* Repère temporaire utilisé pendant les tests. */
body::before {
  content: "Petit écran";
  position: fixed;
  right: 0;
  bottom: 0;
  padding: 0.5rem;
  color: #fff;
  background: #0f172a;
}

@media (min-width: 768px) {
  body::before { content: "Écran intermédiaire"; }
}

@media (min-width: 1024px) {
  body::before { content: "Grand écran"; }
}
b

Vérifier les débordements, la lisibilité et les zones interactives

débordementlisibilitéboutontoucheraccessibilité

Une interface responsive doit rester utilisable, et pas seulement tenir dans l’écran. Il faut rechercher les débordements horizontaux, contrôler la longueur des lignes et vérifier que les liens, champs et boutons possèdent une surface suffisamment grande. Le zoom du navigateur et la navigation au clavier doivent également être testés.

Exemple de code
p { max-width: 70ch; }

button,
.navigation a {
  min-height: 44px;
  padding: 0.75rem 1rem;
}

input,
select,
textarea {
  width: 100%;
  font: inherit;
}
c

Corriger et simplifier les règles CSS

simplificationduplicationhéritagemaintenancecorrection

La finalisation consiste à supprimer les règles devenues inutiles, regrouper les déclarations répétées et vérifier que chaque media query répond à un besoin identifiable. Une feuille trop fragmentée devient difficile à maintenir. Les styles de base doivent rester communs à tous les écrans, tandis que les media queries ne contiennent que les adaptations nécessaires.

Exemple de code
.conteneur {
  width: min(90%, 1200px);
  margin: 0 auto;
}

.cartes {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 640px) {
  .cartes { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .cartes { grid-template-columns: repeat(3, 1fr); }
}
3

Finalisation — Rendre la page responsive

20 minutes · Mobile first · Contrôle sur trois largeurs

Mission

Adaptez la page complète à un téléphone, un écran intermédiaire et un grand écran.

Consignes

  1. Construisez d’abord la version à une colonne destinée aux petits écrans.
  2. Ajoutez une première media query pour répartir les cartes sur deux colonnes.
  3. Ajoutez une seconde media query pour placer le programme et le formulaire côte à côte.
  4. Rendez les images, vidéos et champs de formulaire fluides.
  5. Testez progressivement toutes les largeurs avec le mode responsive.
  6. Corrigez les débordements et vérifiez les zones interactives au clavier et au toucher.
Livrable : les fichiers inscription.html et style.css, utilisables sur téléphone, tablette et ordinateur, prêts à être comparés à une réalisation Bootstrap au chapitre 5.