Arkendia Classrooms
Leçon 13 sur 21 · 17 min

CSS Grid : construire des grilles de mise en page

Flexbox aligne des éléments sur une ligne ou une colonne. Mais quand vous voulez une vraie grille, avec des lignes et des colonnes qui s’alignent entre elles, comme dans un magazine ou une planche-contact, c’est CSS Grid qui prend le relais. Dans cette leçon, vous découvrez ses principes et vous construisez la galerie de projets du portfolio de Camille, sans une seule ligne de calcul de pourcentage.

Flexbox ou Grid ?

Les deux outils sont complémentaires, pas concurrents. Une règle pratique :

  • Flexbox : le contenu dicte la mise en page, en une dimension (une rangée de boutons, un menu) ;
  • Grid : la mise en page dicte la place du contenu, en deux dimensions (une galerie, la structure globale d’une page).

Rien n’interdit de les combiner : une grille pour la structure générale, et du Flexbox à l’intérieur de chaque cellule pour aligner ses éléments.

Créer une grille

Comme avec Flexbox, on déclare display: grid sur le conteneur. On définit ensuite les colonnes avec grid-template-columns :

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

Cette règle crée trois colonnes de même largeur. L’unité fr (pour fraction) représente une part de l’espace disponible : 1fr 2fr donne une première colonne deux fois moins large que la seconde. Les enfants du conteneur se placent automatiquement, ligne après ligne, dans les cellules, et gap (ou row-gap et column-gap) règle les gouttières.

On peut mélanger les unités : grid-template-columns: 12rem 1fr; crée une colonne latérale fixe et une colonne principale qui occupe le reste, la mise en page classique d’un contenu avec un menu latéral.

La fonction repeat()

Écrire 1fr 1fr 1fr 1fr 1fr 1fr devient vite fastidieux. repeat() abrège :

grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(12, 1fr);

Une grille qui s’adapte seule : auto-fit et minmax()

C’est la combinaison qui fait de Grid un outil exceptionnel pour les galeries. Avec minmax(min, max), on définit une taille minimale et une taille maximale pour chaque colonne ; avec auto-fit, le navigateur calcule combien de colonnes tiennent dans la largeur disponible.

.galerie {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.5rem;
}

Lisez-la ainsi : « autant de colonnes que possible, chacune d’au moins 16 rem, et qui se partagent l’espace restant à parts égales ». Sur un grand écran, vous obtiendrez quatre colonnes ; sur une tablette, deux ou trois ; sur un petit téléphone, une seule. Sans aucune media query. Cette ligne est probablement la plus utile de ce chapitre.

Astuce

La différence entre auto-fit et auto-fill : avec auto-fit, les colonnes vides sont réduites à zéro et les colonnes occupées s’étirent pour remplir la ligne ; avec auto-fill, les colonnes vides sont conservées. Pour une galerie qui doit remplir sa ligne, choisissez auto-fit.

Placer les éléments : lignes et colonnes

Les lignes de la grille sont numérotées à partir de 1, et ces numéros servent à placer des éléments précisément. Une grille de trois colonnes possède quatre lignes verticales (1 à 4).

.carte-vedette {
  grid-column: 1 / 3;   /* de la ligne 1 à la ligne 3 : occupe 2 colonnes */
}

.carte-haute {
  grid-row: span 2;     /* occupe 2 rangées */
}

.carte-large {
  grid-column: span 2;  /* occupe 2 colonnes, où qu’elle se trouve */
}

Le mot-clé span est souvent plus souple que des numéros fixes. Une carte « vedette » plus large rend une galerie plus vivante, mais attention à l’adaptation aux petits écrans : une carte qui s’étend sur deux colonnes n’a pas de sens dans une grille d’une seule colonne.

Nommer les zones : grid-template-areas

Pour organiser la structure d’une page, Grid propose une syntaxe presque visuelle : on dessine la mise en page avec des noms de zones.

.page {
  display: grid;
  grid-template-columns: 14rem 1fr;
  grid-template-areas:
    "entete entete"
    "menu   contenu"
    "pied   pied";
  gap: 1rem;
  min-height: 100vh;
}

header { grid-area: entete; }
nav    { grid-area: menu; }
main   { grid-area: contenu; }
footer { grid-area: pied; }

Chaque chaîne représente une rangée, et le nom répété indique qu’une zone s’étend sur plusieurs cellules. Pour changer la disposition sur mobile, il suffit de redéfinir les zones dans une règle de média : on déplace les blocs sans toucher au HTML. Gardez toutefois en tête la remarque sur l’ordre de lecture : le code source doit rester dans un ordre logique.

Aligner dans les cellules

Comme avec Flexbox, des propriétés d’alignement existent :

  • justify-items et align-items alignent le contenu dans chaque cellule (horizontalement, verticalement) ;
  • justify-content et align-content répartissent la grille dans son conteneur quand elle est plus petite que lui ;
  • justify-self et align-self règlent un seul élément ;
  • place-items: center est un raccourci qui centre le contenu des cellules dans les deux directions.
.centre {
  display: grid;
  place-items: center;
  min-height: 50vh;
}

C’est un second moyen de centrer parfaitement un élément, encore plus court qu’avec Flexbox.

Les cartes de projet du portfolio

Mettons la grille en pratique avec des cartes dont la hauteur varie selon la longueur du texte :

<section id="projets">
  <h2>Projets</h2>
  <div class="galerie">
    <article class="carte">
      <img src="images/projets/alpes.jpg" alt="Sommets enneigés" width="800" height="533">
      <h3>Les Alpes en hiver</h3>
      <p>Une série réalisée sur trois semaines.</p>
    </article>
    <!-- autres cartes -->
  </div>
</section>
.galerie {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.5rem;
}

.carte img {
  width: 100%;
  height: auto;
  border-radius: 8px;
}

Par défaut, les cartes d’une même rangée ont la même hauteur (align-items: stretch), ce qui donne une galerie bien alignée. Si les images n’ont pas les mêmes proportions, ajoutez aspect-ratio: 3 / 2; et object-fit: cover; pour qu’elles s’affichent toutes dans un même cadre sans déformation.

Attention

Un élément de grille a par défaut une largeur minimale égale à son contenu : une image très large ou un long mot peut déborder de sa cellule. Donnez toujours max-width: 100% (ou width: 100%) aux images, et utilisez minmax(0, 1fr) si une colonne refuse de rétrécir.

Astuce

L’inspecteur du navigateur propose un mode « grille » qui superpose les lignes numérotées et les noms de zones. Activez-le pour comprendre où sont placés vos éléments : c’est très précieux pour apprendre.

À vous de jouer

  1. Transformez votre section « Projets » en grille adaptative avec auto-fit et minmax(16rem, 1fr) ;
  2. faites occuper à la première carte deux colonnes (sur les écrans larges seulement, vous améliorerez cela à la leçon suivante) ;
  3. donnez à toutes les images du même ratio aspect-ratio et object-fit: cover ;
  4. facultatif : écrivez la structure complète de la page avec grid-template-areas.
Voir une solution
.galerie {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.5rem;
}

.carte:first-child {
  grid-column: span 2;
}

.carte img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 8px;
}

Avec span 2 sur la première carte, la grille doit disposer d’au moins deux colonnes : sur un écran très étroit, la carte demanderait deux colonnes alors qu’il n’en existe qu’une, et la grille en créerait une supplémentaire. C’est pourquoi cette règle sera placée dans une media query dans la prochaine leçon.

À retenir

  • Grid organise en deux dimensions (lignes et colonnes) ; Flexbox en une dimension. Les deux se combinent.
  • grid-template-columns, l’unité fr et repeat() définissent les colonnes ; gap règle les gouttières.
  • repeat(auto-fit, minmax(16rem, 1fr)) crée une grille adaptative sans media query.
  • grid-column, grid-row et span positionnent ou étendent un élément.
  • grid-template-areas permet de dessiner la structure d’une page avec des noms de zones.

La prochaine leçon vous apprend à rendre l’ensemble confortable sur tous les écrans, du plus petit téléphone au grand moniteur.

Publicité
Connectez-vous pour enregistrer votre progression. Se connecter