Vous êtes ici : Accueil du blogCSS, Responsive » Centrer verticalement avec Flexbox

Centrer verticalement avec Flexbox

Si vous avez roulé votre bosse en intégration web, vous savez que le centrage vertical fut longtemps considéré comme l’un des défis les plus périlleux de la discipline :

  • Ère IE6 : Impossible de centrer autre chose qu’une ligne de texte ou une image (sans tableau).
  • Ère IE7 : Des bricolages en « inline-block » font leur apparition pour centrer les blocs.
  • Ère IE8 : Du neuf avec du vieux grâce au modèle tabulaire sémantique « CSS table ».
  • Ère IE9/10 : Décalages dans l’espace avec « CSS3 Transform ».
  • Ère IE10/11 : Révolution « CSS Flexible Box Layout Module », ou « Flexbox ».

Si la compatibilité IE10 (et versions antérieures, ~1% des utilisateurs mondiaux en 2018) ne fait pas partie de votre cahier des charges, vous pouvez utiliser sereinement Flexbox en production quand il s’agit d’aligner verticalement. Pour le centrage horizontal, ça se passe ici. Cet article met en avant les solutions les plus souples et fonctionnelles des tests suivants :

Voir tous les tests

  • Support : Firefox/Chrome/Safari/Edge (2016+) et Internet Explorer 11. La page de test propose des correctifs pour Internet Explorer 10 qui ne figurent pas dans cet article pour des raisons de pérennité.
  • Les situations en conteneurs fluides ne sont pas présentées dans cet article, mais les techniques abordées ci-dessous fonctionnent aussi bien en hauteur fixe qu’en hauteur libre.
  • La largeur des blocs est laissée telle quelle afin d’observer l’impact du contexte flex. Il suffit d’appliquer un width: 100% sur l’élément centré pour que sa largeur s’adapte à celle de son parent.
  1. [#] Comment centrer verticalement des éléments ?
  2. [#] Comment centrer du contenu dans un bloc en hauteur 100% ?
  3. [#] Internet Explorer, min-height et centrage vertical

Comment centrer verticalement des éléments ?

Qu’il s’agisse d’un texte, d’un bloc, d’une image :

<div class="container">
   Lorem ipsum
</div>
<div class="container">
   <div class="block">
      Lorem ipsum
   </div>
</div>
<div class="container">
   <img src="image.png">
</div>

Ou d’une liste d’éléments :

<div class="container">
   <div class="block">Lorem ipsum</div>
   <div class="block">Lorem ipsum [...]</div>
</div>
<div class="container">
   <img src="image-1.png">
   <img src="image-2.png">
</div>

La formule magique à appliquer sera la même :

.container {
   display: flex;
   align-items: center;
}

On définit un contexte flex et on précise avec align-items l’alignement des enfants flex sur l’axe perpendiculaire à l’axe principal. L’axe principal est horizontal parce que nous ne l’avons pas modifié avec flex-direction, qui est row par défaut (« ligne », en opposition à column). L’axe perpendiculaire à l’axe principal est donc ici vertical.

Modifier l’alignement vertical d’un bloc à contenu long

Par défaut, un bloc qui excède en hauteur la taille de son parent restera centré verticalement :

.container {
   display: flex;
   align-items: center;
}

.container, .block {
   overflow: hidden;
}

Voici une petite astuce pour aligner l’élément en haut en cas de contenu long, sans perturber le centrage vertical d’un contenu court :

<div class="container">
   <div class="block block--top">
      Lorem ipsum [...]
   </div>
</div>
<div class="container">
   <div class="block block--top">
      Lorem ipsum
   </div>
   <div class="block block--top">
      Lorem ipsum [...]
   </div>
</div>
.block--top {
   max-height: 100%;
}

On indique simplement aux éléments qu’ils ne doivent pas prendre plus de 100% de la hauteur de leur parent.

Comment centrer du contenu dans un bloc en hauteur 100% ?

Nous avons vu précédemment comment aligner verticalement un élément. La technique suivante montre comment aligner verticalement un contenu dans un élément en hauteur 100%, c’est à dire qui occupe toute la hauteur de son parent :

<div class="container">
   <div class="block">
      Lorem ipsum
   </div>
</div>
<div class="container">
   <div class="block">
      Lorem ipsum
   </div>
   <div class="block">
      Lorem ipsum [...]
   </div>
</div>
.container {
   display: flex;
}

.block {
   display: flex;
   align-items: center;
}

Par défaut, un enfant flex prendra toujours la hauteur de son parent. L’astuce consiste donc à décaler d’un niveau le centrage vertical, en l’appliquant directement sur l’élément.

Dealing with flex context

Si votre bloc contient des éléments internes (<div>, <span>, whatever…), notez que ceux-ci évolueront dans le contexte flex hérité par le parent. Protégez vos enfants des effets de bord indésirables à l’aide d’un conteneur tampon :

<div class="container">
   <div class="block">
      <span>Lorem ipsum [...]<span>
      <span>consectetur [...]<span>
   </div>
</div>
<div class="container">
   <div class="block">
      <div class="block-inner">
         <span>Lorem ipsum [...]<span>
         <span>consectetur [...]<span>
      </div>
   </div>
</div>

Internet Explorer, min-height et centrage vertical

Sous IE10 et IE11, les éléments flex ignorent la hauteur du parent si celle-ci est définie avec min-height (plus d’infos). Pour régler le problème, il suffit d’ajouter un conteneur supplémentaire et de lui appliquer les correctifs suivants :

<div class="iefix">
   <div class="container">
      <div class="block">
         Lorem ipsum
      </div>
   </div>
</div>
.iefix {
   display: -ms-flexbox;
   -ms-flex-direction: column;
}

Vous pourrez retrouver une mise en situation de ce correctif (et de toutes les techniques abordées dans cet article) sur la page de test :

Voir tous les tests

Laisser un commentaire

Balises HTML autorisées dans la rédaction du message :
<strong> <a> <code> <q>

Les champs marqués d'une étoile sont obligatoires.

Current month ye@r day *