Centrer en CSS, un guide complet
Le centrage en CSS est souvent un véritable casse-tête, car il existe plusieurs techniques différentes selon les cas d'utilisation. Chris Coyier les a listées et nous donne toutes les solutions.
Le centrage en CSS est souvent un casse-tête. Pourquoi faut-il que ce soit si difficile ? En fait, la difficulté ne vient pas du centrage lui-même mais de la multiplicité des techniques disponibles pour centrer en CSS et qui dépendent chacune de la situation. La vraie difficulté est donc de savoir quelle technique utiliser dans une situation donnée.
Nous allons lister toutes ces situations et en principe vous serez équipé pour la route.
NdT : Chris Coyier s'intéresse ici au centrage en général, pour une introduction complète au centrage d'une div, consultez l'article Centrer un bloc Div, guide complet, de Steve Pear.
Si je veux centrer...
Centrer horizontalement
Éléments inline ou inline-* (p.ex. texte ou lien)?
Vous pouvez centrer horizontalement des éléments inline à l'intérieur d'un élément parent de niveau bloc avec cette ligne simple :
//CSS
.center-children {
text-align: center;
}
Voici ce que ça donne sur Code Pen (comme toujours, vous pouvez cliquer sur HTML et CSS pour voir le code, sur Result pour voir le résultat, et sur Edit si vous voulez voir l'original sur Code Pen et jouer avec) :
Ça fonctionnera très bien avec inline, inline-block, inline-table, inline-flex, etc.
Éléments block ?
Vous pouvez centrer un élément de niveau bloc en lui donnant une marge gauche et droite automatique, ce qui se traduit par :
//CSS
.center-me {
margin: 0 auto;
}
NB : Il va de soi que l'élément en question a une largeur déterminée, sinon il prendrait toute la largeur de l'élément parent et n'aurait pas besoin d'être centré.
Ça marchera quelle que soit la largeur de l'élement bloc que vous voulez centrer ou celle de son élément parent.
Y a-t-il plus d'un élément block ?
Si vous avez deux éléments blocs, ou plus, à centrer dans une rangée, une bonne solution consistera souvent à changer le type de display
. Voici deux exemples, le premier utilise display: inline-block
, le second utilise Flexbox :
Voilà pour les rangées. Et si vous avez plusieurs éléments blocks empilés les uns sur les autres, la technique de marge automatique fonctionne parfaitement :
Centrer verticalement
Le centrage vertical est un peu plus délicat en CSS.
Éléments inline ou inline-* (p.ex. texte ou lien)?
Est-ce une ligne unique ?
Des éléments inline ou texte peuvent apparaître centrés verticalement parfois simplement parce qu'il y a un padding top et bottom égal :
//CSS
.link {
padding-top: 30px;
padding-bottom: 30px;
}
Si vous ne pouvez pas utiliser le padding et que vous cherchez à centrer un texte qui doit rester sur une ligne unique, le truc est de donner à la propriété line-height
la même valeur qu'à height
.
//CSS
.center-text-trick {
height: 100px;
line-height: 100px;
white-space: nowrap;
}
Ou des lignes multiples ?
Là aussi on peut obtenir le centrage avec des padding top et bottom égaux.
Si pour une raison quelconque vous ne pouvez pas utiliser cette technique, peut-être l'élément dans lequel est situé le texte est-il une cellule de tableau, ou bien on peut forcer cet élément à se comporter comme s'il était une cellule. La propriété vertical-align
gère cette situation, puisqu'elle sert habituellement à aligner des contenus situés sur une rangée.
Une autre solution consiste à utiliser flexbox. Centrer un flex-child dans un flex-parent est assez facile :
//CSS
.flex-center-vertically {
display: flex;
justify-content: center;
flex-direction: column;
height: 400px;
}
N'oubliez pas que cela fonctionne uniquement si le container parent a une hauteur fixe (en px, en % ou ce que vous voulez), c'est pourquoi le container ici a une hauteur.
Si vous ne pouvez utiliser aucune de ces techniques, il vous reste encore celle du “ghost-element”, l'élément fantôme, dans lequel un pseudo-élément prenant toute la hauteur est placé à l'intérieur du container et le texte est aligné verticalement sur lui :
//CSS
.ghost-center {
position: relative;
}
.ghost-center::before {
content: " ";
display: inline-block;
height: 100%;
width: 1%;
vertical-align: middle;
}
.ghost-center p {
display: inline-block;
vertical-align: middle;
}
Élements block
Connaissez-vous la hauteur de l'élément ?
Il est assez courant de ne pas connaître la hauteur d'un élément, pour des tas de raisons : Si la largeur change, la réorganisation du texte peut changer la hauteur, une modification du style du texte peut également changer la hauteur, de même qu'un ajout de texte... Idem si le ratio d'aspect de votre image est fixe, tout redimensionnement entraînera une modification de sa hauteur.
Mais si vous connaissez sa hauteur, vous pouvez le centrer avec :
//CSS
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}
La hauteur de l'élément est-elle inconnue ?
Si vous ne connaissez pas la hauteur de l'élément, vous pouvez le centrer en le remontant de la moitié de sa hauteur après l'avoir fait descendre de la moitié de la hauteur du contenant :
//CSS
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
Pouvez-vous utiliser Flexbox ?
Sans surprise, c'est bien plus facile avec flexbox.
//CSS
.parent {
display: flex;
flex-direction: column;
justify-content: center;
}
Horizontalement et verticalement
Vous pouvez combiner les techniques qui précèdent pour obtenir des éléments parfaitement centrés. Mais il me semble qu'elles peuvent se regrouper en trois catégories :
Éléments de hauteur et largeur fixes
Vous pouvez utiliser des marges négatives égales à la moitié de cette hauteur et de cette largeur, un positionnement absolu à 50%/50% centrera l'élément :
//CSS
.parent {
position: relative;
}
.child {
width: 300px;
height: 100px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
margin: -70px 0 0 -170px;
}
Éléments de hauteur et largeur inconnues
Si vous ne connaissez pas la largeur ou la hauteur, vous pouvez utiliser la propriété transform
et une translation négative de 50% dans les deux directions (elle sera basée sur les largeur et hauteur actuelles de l'élément) :
//CSS
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Pouvez-vous utiliser Flexbox ?
Pour centrer dans les deux directions avec flexbox, vous devez utiliser deux propriétés de centrage :
//CSS
.parent {
display: flex;
justify-content: center;
align-items: center;
}
Conclusion
Centrer horizontalement, centrer verticalement, vous pouvez tout centrer sans problème en CSS !