Au bon vieux temps, les limites de CSS étaient telles que même des choses « simples » comme le centrage vertical représentaient un défi, certains d’entre nous s’appuyant même sur des solutions JavaScript. C’était fragile, c’était très contraint, et il y avait toujours cette exception qui le faisait échouer.
Que nous essayions d’aligner une icône ou une image à côté du texte, de créer l’une de ces bannières « héros » populaires, ou une superposition modale, centrer les choses dans l’axe vertical était toujours une lutte.
Mais CSS a fait un long chemin depuis, fournissant beaucoup de méthodes qui ont rendu le centrage vertical plus facile à chaque fois. Voici un résumé de certaines d’entre elles, ainsi que leurs cas d’utilisation et leurs limites.
Positionnement absolu et marge auto
Un élément sans dimension intrinsèque peut être « centré » en utilisant simplement des valeurs égales du haut et du bas. Lorsque l’élément a des dimensions intrinsèques, nous pourrions utiliser 0 pour le haut et le bas, puis appliquer margin auto. Cela permettra de centrer automatiquement l’élément :
.container{ position:relative;}.element{ position:absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; height: 20px; /*requires explicit height*/}
Voir le stylo
Centering 1 : absolute positioning par Facundo Corradini (@facundocorradini)
sur CodePen.
La limitation est, bien sûr, que la hauteur de l’élément doit être explicitement déclarée, sinon il occupera tout le conteneur.
Le classique top 50% translate -50%
C’est l’un des premiers, et toujours un go-to, pour de nombreux développeurs. Une astuce simple, reposant sur le positionnement absolu de l’élément interne à 50% du haut de leur parent, puis sa translation vers le haut de 50% de sa hauteur:
.container{ position: relative;}.element{ position: absolute; top: 50%; transform: translateY(-50%);}
Voir le stylo
Centering 2 : top 50 translateY -50 par Facundo Corradini (@facundocorradini)
sur CodePen.
Une approche assez solide, la seule limitation majeure étant l’utilisation de translate qui pourrait gêner d’autres transformations, par exemple lors de l’application de transitions/animations.
Tables. Ouaip, je viens de dire tables.
Une approche vraiment simple et l’une des premières (à l’époque, tout était des tables), consiste à utiliser le comportement des cellules de table et de vertical-align pour centrer un élément sur le conteneur.
Cela peut être fait avec des tableaux réels (honte, honte, honte), ou en utilisant du HTML sémantique, en basculant l’affichage de l’élément sur table-cell:
.container{ display: table; height: 100%;}.element{ display: table-cell; text-align: center; vertical-align: middle;}
Voir le stylo
Centering 3 : tables par Facundo Corradini (@facundocorradini)
sur CodePen.
Cela fonctionne même lorsque les deux éléments sont de hauteur inconnue. La principale limitation est bien sûr si vous avez besoin d’avoir un frère ou une sœur non centré, et cela pourrait devenir délicat avec les limites de l’arrière-plan.
En outre, gardez à l’esprit que cela échoue totalement sur les lecteurs d’écran (même si votre balisage est basé sur des divs, le réglage de l’affichage CSS sur table et table-cell fera que les lecteurs d’écran l’interpréteront comme un tableau réel). Loin d’être le meilleur en matière d’accessibilité.
La méthode de l’élément fantôme
Une autre vieille méthode, qui n’a pas rattrapé son retard pour une raison quelconque, consiste à utiliser inline-block avec un (pseudo) élément fantôme qui a 100% de la hauteur du parent, puis à définir la propriété vertical-align sur middle :
.container::before { content: ''; display: inline-block; height: 100%; vertical-align: middle; margin-left: -1ch;}.element{ display: inline-block; vertical-align: middle;}
Voir la méthode Pen
Centering 4 : ghost element par Facundo Corradini (@facundocorradini)
sur CodePen.
Elle fonctionne en fait assez bien, le « gotcha » le plus notable étant qu’elle déplace le centre horizontal juste un tout petit peu vers la droite, à cause du comportement toujours croustillant des espaces blancs entre les éléments inline-block.
Ceci peut être traité comme nous le ferions avec la question de l’inline-block dans n’importe quel autre contexte, l’approche la plus simple étant la margin-left -1ch que j’ai utilisée ci-dessus (bien que cela ne sera pas 100% précis sauf sur les polices monospace, car l’unité ch signifie la largeur du caractère « 0 »), ou le réglage de la taille de la police à 0 sur le conteneur puis la réinitialisation à px ou rem sur l’élément. Pas optimal, c’est le moins que l’on puisse dire.
Marge auto sur un élément flex
En entrant enfin dans le territoire CSS moderne, flexbox a introduit un comportement assez impressionnant pour les marges automatiques. Désormais, il ne se contente pas de centrer horizontalement l’élément comme il le faisait dans les dispositions en blocs, mais le centre également dans l’axe vertical :
.container{ display:flex;}.element{ margin:auto;}
Voir le stylo
Centering 5 : margin:auto on a flex-item par Facundo Corradini (@facundocorradini)
sur CodePen.
Cette tactique est l’une de mes préférées en raison de sa simplicité, la seule limitation majeure est qu’elle ne fonctionnera qu’avec un seul élément.
Pseudo-éléments sur un flex-container
Ce n’est pas l’approche la plus pratique du monde, mais nous pouvons également utiliser des pseudo-éléments flexibles et vides pour pousser l’élément au centre :
.container{ display:flex;}.element{ margin:auto;}
Voir le stylo
Centering 6 : pseudos on a flexbox by Facundo Corradini (@facundocorradini)
on CodePen.
Cela peut être utile lorsque nous voulons garder un espacement flexible sur un flex-container orienté colonne avec plusieurs éléments.
7 & 8. Aligner sur le conteneur flex ou l’élément flex
Flexbox a également introduit des propriétés d’alignement vraiment géniales (qui sont maintenant bifurquées dans leur propre module d’alignement de boîte). Cela nous permet de contrôler comment les éléments sont placés et comment l’espace vide est distribué d’une manière qui aurait nécessité soit des nombres magiques en CSS pour un nombre spécifique d’éléments (ou un JS assez intelligent pour des quantités dynamiques).
Selon la direction du flex, nous pourrions utiliser justify-content ou align-items pour ajuster selon les besoins.
Sur le conteneur :
.container{ display: flex; justify-content: center; align-items: center;}
Voir le stylo
Centering 7 : align on flex-container par Facundo Corradini (@facundocorradini)
sur CodePen.
Sur un flex-item particulier:
.container{ display: flex;}.element{ align-self: center; margin: 0 auto;}
Voir le stylo
Centering 8 : align on flex-item par Facundo Corradini (@facundocorradini)
sur CodePen.
Pas beaucoup d’inconvénients à cela, sauf si vous devez supporter des navigateurs plus anciens. IE 11 devrait fonctionner, mais son implémentation de flexbox est assez boguée, donc il doit toujours être traité avec une attention supplémentaire. IE 10 nécessite un travail supplémentaire car il est basé sur une ancienne version de la spécification qui a une syntaxe différente, et nécessite le préfixe fournisseur -ms.
9 & 10. Alignement sur le conteneur de grille ou l’élément de grille
CSS Grid inclut à peu près les mêmes options d’alignement que flexbox, nous pouvons donc l’utiliser sur le conteneur de grille :
.container{ display: grid; align-items: center; justify-content: center;}
Voir le stylo
Centering 9 : align on grid-container par Facundo Corradini (@facundocorradini)
sur CodePen.
Ou juste sur un élément de grille spécifique:
.container{ display: grid;}.element{ justify-self: center; align-self: center}
Le manque de support des navigateurs hérités est la seule limitation pour cette technique.
Voir le stylo
Centering 10 : align on grid-item par Facundo Corradini (@facundocorradini)
sur CodePen.
Pseudo-éléments sur une grille
De manière similaire à l’alternative flexbox, nous pourrions utiliser une grille à trois rangées avec des pseudo-éléments :
.container{ display: grid; grid-template-columns: 1fr; grid-template-rows: repeat(3, 1fr);}.container::before,.container::after{ content:"";}
Rappellez-vous que 1fr signifie en fait minmax(auto, 1fr), donc les rangées vides ne prendront pas nécessairement un tiers de la hauteur du conteneur. Elles se réduiront au besoin jusqu’à leur valeur minimale de auto, et sans contenu, signifie 0.
Voir le Pen
Centering 11 : grid + pseudos par Facundo Corradini (@facundocorradini)
sur CodePen.
Cette approche peut sembler idiote, mais elle nous permet de réaliser facilement l’une de mes astuces CSS Grid préférées : combiner des lignes fr avec des lignes minmax, ce qui fera que les lignes fr vides s’effondreront en premier, puis les lignes mixmax. Jenn Simmons a de très bons exemples à ce sujet.
Donc, le fait que les pseudos prennent les rangées entièrement collapables permettra à l’algorithme de placement automatique d’exercer sa magie sur nos éléments réels. Sauf si nous devons prendre en charge IE, qui manque d’auto-placement. Ce qui nous amène à la méthode suivante…
Placement explicite des lignes de la grille
La grille CSS permet de placer explicitement des éléments sur une ligne spécifique, donc la même déclaration de grille que ci-dessus et l’élément placé sur la deuxième ligne suffiront :
.container{ display:grid; grid-template-columns:1fr; grid-template-rows: repeat(3, 1fr);}.element{ grid-row: 2 / span 1; /* or grid-row: 2/3 */}
Cette dernière peut fonctionner jusqu’à IE10. Croyez-le ou non, IE a été l’un des premiers et des plus fervents défenseurs de la grille CSS, l’expédiant tout le chemin du retour en 2011 avec IE10. Il est basé sur une ébauche vraiment précoce qui a une syntaxe complètement différente, mais nous pouvons le faire fonctionner :
.container{ display: -ms-grid; -ms-grid-rows: (1fr); -ms-grid-columns: 1fr;}.element{ -ms-grid-column: 1; -ms-grid-row: 2;}
See the Pen
Centering 12 : explicit placement on a grid by Facundo Corradini (@facundocorradini)
on CodePen.
Margin auto sur un élément de grille
De manière similaire à flexbox, appliquer margin-auto sur un élément de grille le centre sur les deux axes.
.container{ display: grid;}.element{ margin: auto;}
Voir le stylo
Centering 12 : placement explicite sur une grille par Facundo Corradini (@facundocorradini)
sur CodePen.
Quelques (probables) futures implémentations
Selon la spécification CSS Box Alignment Module level 3, align-content devrait fonctionner sur l’axe de bloc des conteneurs de blocs et des conteneurs multicolores, donc (si les navigateurs l’implémentent) nous devrions pouvoir centrer le contenu de ces conteneurs comme nous le faisons dans les conteneurs flex ou grid.
Essayez LogRocket pour être sûr à 100% que vos éléments sont correctement centrés
« Ça a l’air bien sur ma machine » n’est pas suffisant. Avec LogRocket, vous pouvez voir le DOM (ainsi que ces pesants éléments centrés verticalement) exactement comme le fait l’utilisateur final. Si vous êtes intéressé par la surveillance et le suivi de l’utilisation du CPU côté client, de l’utilisation de la mémoire, et plus encore pour tous vos utilisateurs en production, essayez LogRocket.https://logrocket.com/signup/
LogRocket est comme un DVR pour les applications web, enregistrant tout ce qui se passe dans votre application ou site web. Au lieu de deviner pourquoi les problèmes surviennent, vous pouvez agréger et faire des rapports sur les principales mesures de performance frontales, rejouer les sessions utilisateur en même temps que l’état de l’application, enregistrer les requêtes réseau et remonter automatiquement à la surface toutes les erreurs.
Modernisez la façon dont vous déboguez vos applications web – Commencez la surveillance gratuitement.