Chapitre 28 : Alignement et espacement avancé dans Grid et Flexbox
Concepts clés : gap, align-content, justify-self
L'alignement et l'espacement sont les piliers d'une interface utilisateur professionnelle. Si les bases de Flexbox et Grid permettent de positionner des éléments, la maîtrise des propriétés avancées d'alignement et de distribution d'espace permet de passer d'une mise en page "qui fonctionne" à une mise en page "pixel-perfect" et adaptable.
Ce chapitre explore la gestion fine des espaces vides et le positionnement individuel des éléments au sein de leurs conteneurs.
La propriété Gap
1. Quoi
La propriété gap (anciennement grid-gap pour Grid) définit l'espacement constant entre les lignes et les colonnes d'un conteneur Flexbox ou Grid. Contrairement aux marges (margin), le gap ne s'applique qu'entre les éléments, et non sur les bords extérieurs du conteneur.
Elle se décompose en deux propriétés spécifiques :
row-gap: L'espace vertical entre les lignes.column-gap: L'espace horizontal entre les colonnes.
2. Pourquoi
L'utilisation des marges pour créer de l'espace entre des éléments (le pattern margin-right ou margin-bottom) crée souvent des problèmes de "bordure" : le dernier élément de la ligne possède une marge inutile qui décale l'alignement global ou nécessite l'utilisation de sélecteurs complexes comme :last-child { margin-right: 0; }.
gap résout ce problème nativement en ignorant les bords extérieurs, simplifiant ainsi radicalement le CSS et rendant le design plus robuste lors du passage en mode responsive.
3. Comment
A. Syntaxe de base
.container {
display: grid; /* ou flex */
gap: 20px; /* Applique 20px verticalement et horizontalement */
}
.container-specific {
display: grid;
row-gap: 10px;
column-gap: 30px;
}
B. Cas concret : Grille de cartes de produits
Dans un catalogue e-commerce, on souhaite un espacement régulier entre les cartes, tout en gardant un contrôle strict sur le padding du conteneur parent.
.product-grid {
display: grid;
/* Création de colonnes adaptatives avec un minimum de 250px */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
/* Espacement constant entre les cartes */
gap: 2rem;
/* Le padding gère l'espace extérieur, le gap gère l'espace intérieur */
padding: 2rem;
background-color: #f5f5f5;
}
.product-card {
background: white;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
C. Limitations
- Compatibilité Flexbox : Bien que
gapsoit désormais largement supporté dans Flexbox (Safari 14.1+), certains très vieux navigateurs ne le gèrent que pour Grid. - Interaction avec
margin: auto: Si un élément possèdemargin: auto, il peut "pousser" et ignorer visuellement l'effet du gap en occupant tout l'espace disponible.
4. Zone de Danger
❌ Erreur commune : Utiliser margin sur tous les enfants pour créer de l'espace.
/* MAUVAIS : crée un décalage sur le bord droit et bas */
.item {
margin: 10px;
}
✅ Bonne pratique : Utiliser gap sur le parent.
/* BIEN : espace uniquement l'intérieur */
.container {
display: flex;
gap: 10px;
}
Alignement du contenu : align-content
1. Quoi
align-content définit l'alignement des lignes de contenu sur l'axe transverse (axe vertical en flex-direction: row).
Attention cruciale : Cette propriété n'a d'effet que si :
- Le conteneur a une hauteur définie (ou une hauteur minimale).
- Le contenu "wrap" (est réparti sur plusieurs lignes) via
flex-wrap: wrapou s'il s'agit d'une grille CSS.
2. Pourquoi
Alors que align-items aligne les éléments à l'intérieur de leur ligne respective, align-content aligne le bloc entier de lignes par rapport au conteneur. C'est l'outil indispensable pour centrer verticalement un groupe de lignes ou les répartir uniformément dans un espace disponible.
3. Comment
A. Syntaxe de base
.container {
display: flex;
flex-wrap: wrap;
height: 500px;
align-content: center; /* Centre tout le bloc de lignes verticalement */
}
B. Cas concret : Galerie d'images centrée
Imaginez une galerie où le nombre d'images varie. Vous voulez que, peu importe le nombre de lignes créées, le bloc global soit centré verticalement dans la section.
.gallery-section {
display: flex;
flex-wrap: wrap;
gap: 1rem;
/* On définit une hauteur pour voir l'effet de align-content */
min-height: 80vh;
/* Répartit les lignes uniformément avec un espace entre elles */
align-content: space-around;
justify-content: center; /* Centre horizontalement */
}
.gallery-item {
flex: 0 1 200px;
height: 150px;
background: #ddd;
}
C. Limitations
- Ligne unique : Si vous n'avez qu'une seule ligne d'éléments (pas de wrap),
align-contentne fera absolument rien. Utilisezalign-itemsdans ce cas.
4. Zone de Danger
❌ Confusion align-items vs align-content : Essayer de centrer verticalement un bloc de plusieurs lignes avec align-items: center. Cela centrera chaque élément dans sa ligne, mais les lignes resteront collées en haut du conteneur.
✅ Bonne pratique :
align-items→ Alignement interne à la ligne.align-content→ Alignement du groupe de lignes.
Différence align-items vs align-content
Alignement individuel : justify-self
1. Quoi
justify-self permet à un élément individuel de modifier son alignement sur l'axe principal (horizontal en Grid).
Note fondamentale : justify-self ne fonctionne pas en Flexbox. En Flexbox, l'alignement horizontal individuel se gère via margin: auto. En Grid, justify-self est pleinement opérationnel.
2. Pourquoi
Dans une grille, on veut souvent que la majorité des éléments occupent tout l'espace de leur cellule, mais qu'un élément spécifique (comme un bouton "Supprimer" ou un badge) soit aligné à droite ou au centre de sa propre cellule sans affecter les autres.
3. Comment
A. Syntaxe de base (Grid uniquement)
.grid-item {
justify-self: end; /* Aligne l'élément à la fin de sa cellule (droite) */
}
B. Cas concret : Tableau de bord administratif
Création d'une ligne de tableau en Grid où le nom est à gauche, le statut au centre, et l'action à droite.
.admin-row {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
gap: 1rem;
align-items: center;
padding: 1rem;
border-bottom: 1px solid #eee;
}
.user-name {
justify-self: start; /* Aligné à gauche */
font-weight: bold;
}
.user-status {
justify-self: center; /* Aligné au centre de sa colonne */
font-size: 0.8rem;
}
.user-action {
justify-self: end; /* Aligné à droite de sa colonne */
}
C. Limitations
- Flexbox : Comme mentionné,
justify-selfest ignoré en Flexbox. Pour obtenir le même effet, utilisezmargin-left: autosur l'élément pour le pousser vers la droite.
4. Zone de Danger
❌ Erreur commune : Tenter d'utiliser justify-self dans un conteneur display: flex.
.flex-item {
display: flex;
justify-self: end; /* ❌ NE FONCTIONNE PAS */
}
✅ Bonne pratique :
- En Grid →
justify-self: end. - En Flexbox →
margin-left: auto.
Questions clés
1. Quelle est la différence fondamentale entre gap et margin ?
Découvrir la réponse
Le gap définit l'espace entre les éléments d'un conteneur Flex ou Grid, sans ajouter d'espace sur les bords extérieurs du conteneur. La margin s'ajoute autour de chaque élément, ce qui crée souvent des espaces indésirables sur les bords du parent, nécessitant des corrections manuelles.
2. Pourquoi align-content semble-t-il ne pas fonctionner dans mon conteneur Flexbox ?
Découvrir la réponse
Il y a généralement deux raisons possibles :
- Soit vous n'avez pas défini de hauteur (
heightoumin-height) pour le conteneur, donc celui-ci s'adapte exactement à la taille du contenu, laissant aucun espace vide à distribuer. - Soit vous n'avez pas activé
flex-wrap: wrap.align-contentne s'applique qu'aux conteneurs multi-lignes.
3. Comment aligner un seul élément à droite dans une ligne Flexbox ?
Découvrir la réponse
Puisque justify-self ne fonctionne pas en Flexbox, la méthode idiomatique consiste à appliquer margin-left: auto à l'élément concerné. Cela forcera l'élément à consommer tout l'espace disponible à sa gauche, le poussant ainsi vers la droite.
4. Quelle propriété utiliser pour centrer verticalement un élément unique dans une cellule Grid ?
Découvrir la réponse
Pour l'alignement vertical (axe transverse) d'un seul élément, on utilise align-self: center. Pour l'alignement horizontal (axe principal) dans la cellule, on utilise justify-self: center.
Mise en pratique
Exercice 1 : Reproduction guidée
Objectif : Créer une grille de 3x3 cartes avec un espacement constant.
- Créez un conteneur
.grid-containeravecdisplay: grid. - Définissez 3 colonnes égales.
- Appliquez un espacement de
25pxentre toutes les cartes en utilisant une seule propriété. - Ajoutez un padding de
20pxau conteneur pour éviter que les cartes ne collent aux bords de la page.
Découvrir la solution commentée
.grid-container {
display: grid;
/* 3 colonnes égales */
grid-template-columns: repeat(3, 1fr);
/* Utilisation de gap pour l'espacement interne uniquement */
gap: 25px;
/* Padding pour l'espace extérieur */
padding: 20px;
}
.card {
background: #eee;
height: 100px;
border: 1px solid #ccc;
}
Exercice 2 : Adaptation
Objectif : Gérer un alignement vertical complexe.
- Créez un conteneur Flexbox de
600pxde hauteur. - Ajoutez 6 éléments enfants (divs) avec une largeur de
200pxet une hauteur de100px. - Activez le wrap.
- Faites en sorte que les lignes de cartes soient regroupées et centrées verticalement au milieu du conteneur, tout en gardant un espace de
20pxentre chaque carte.
Découvrir la solution commentée
.container {
display: flex;
flex-wrap: wrap; /* Obligatoire pour align-content */
height: 600px;
/* Centre le bloc de lignes verticalement */
align-content: center;
/* Espacement entre les éléments */
gap: 20px;
border: 2px solid black;
}
.item {
width: 200px;
height: 100px;
background: lightblue;
}
Exercice 3 : Conception
Objectif : Créer un header de navigation "Hybrid Grid".
- Créez un header avec
display: gridet 3 colonnes :[Logo] [Menu] [Actions]. - Le Logo doit être aligné à gauche (
start). - Le Menu doit être centré horizontalement dans sa cellule.
- Le bloc Actions doit être aligné à droite (
end). - Tous les éléments doivent être centrés verticalement.
- Ajoutez un espacement de
1.5rementre les colonnes.
Découvrir la solution commentée
.header {
display: grid;
/* Logo prend l'espace nécessaire, Menu prend le reste, Actions l'espace nécessaire */
grid-template-columns: auto 1fr auto;
/* Alignement vertical global pour tous les enfants */
align-items: center;
/* Espacement entre colonnes */
gap: 1.5rem;
padding: 1rem 2rem;
background: #333;
color: white;
}
.logo {
justify-self: start; /* Aligné à gauche de sa cellule */
}
.menu {
justify-self: center; /* Centré dans sa cellule */
display: flex;
gap: 1rem;
}
.actions {
justify-self: end; /* Aligné à droite de sa cellule */
}