La Cascade

Un peu de tout sur CSS, HTML, SVG et JS,traduit du web anglophone
Rechercher

Centrer en CSS, un guide complet

par Chris Coyier, 6 septembre 2014, css, flexbox, article original paru le 2 septembre 2014 dans CSS-Tricks

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) :

voir Centering Inline Elements de Chris Coyier dans CodePen

Ç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 :

voir Centering Row of Blocks de Chris Coyier dans CodePen

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;
}
voir Centering a line with line-height de Chris Coyier dans CodePen

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;
}
voir Ghost Centering Multi Line Text de Chris Coyier dans CodePen

É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; */
}
voir Center Block with Fixed Height de Chris Coyier dans CodePen

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%);
}
voir Center Block with Unknown Height de Chris Coyier dans CodePen

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 !

Autres ressources externes

Articles de Chris Coyier traduits dans La Cascade

Voir la page de Chris Coyier et la liste de ses articles dans La Cascade.
Article original paru le 2 septembre 2014 dans CSS-Tricks
Traduit avec l'aimable autorisation de CSS-Tricks et de Chris Coyier.
Copyright CSS-Tricks © 2014