Centrer une image dans un conteneur plus petit

Aujourd'hui, en faisant l'intégration d'un site en Drupal, s'est posé une petite colle, sur la mise en page de certaines fiches présentant des professionnels, dûe à la conjoncture de plusieurs éléments :

  • La photo était aligné au pixel près en hauteur avec un bandeau graphique,
  • Les photos n'avaient pas toutes les mêmes dimensions (photos d'identité fournies par le client),
  • Les photos n'avaient pas le même ratio (mais toutes étaient des photos d'identité classique orientées en portrait).

Je pensais m'en sortir avec un simple alignement centré de l'image dans son conteneur, mais ça ne rendait pas le résultat escompté, l'image n'étant pas centrée lorsque son élément parent était plus étroit qu'elle même.

La solution retenue a été d'utiliser deux wrappers, plus faciles à positionner l'un par rapport à l'autre et ensuite de positionner l'image dedans. Il est ainsi possible de rogner en html et css l'image (en faisant attention à ne pas appeler des posters, mais dans mon cas, ça convenait).


Passons au balisage, avec le HTML d'abord :

<!doctype html />
<html>
<head>
<title>foo</title>
</head>
<body>
<div id="gallery">
<div class="outter-image-wrapper">
<div class="inner-image-wrapper">
<img src="http://lorempixel.com/200/400/technics/" alt="Cette image fait 200 pixels de large et 400 pixels de haut" />
</div>
</div>
<div class="outter-image-wrapper">
<div class="inner-image-wrapper">
<img src="http://lorempixel.com/150/300/technics/" alt="Cette image fait 150 pixels de large et 300 pixels de haut" />
</div>
</div>
<div class="outter-image-wrapper">
<div class="inner-image-wrapper">
<img src="http://lorempixel.com/200/350/technics/"alt="Cette image fait 200 pixels de large et 350 pixels de haut" />
</div>
</div>
</div>
</body>
</html>

Ce qui nous donne le rendu suivant :

Ensuite, on crée les styles CSS suivants :

/* On crée les styles qui s'appliqueront aux wrappers extérieurs,
 * Ceux là même qui détermineront le cadre de l'image
 * On les fait flotter à gauche pour les aligner,
 * On fixe la largeur (100px),
 * On masque ce qui dépasse avec l'overflow : hidden;
 * et une marge droite, pour faire plus joli sinon c'est tout beurk et tout collé */
.outer-image-wrapper {
  float: left;
  height: 200px;
  margin-right: 10px;
  overflow: hidden;
  width: 100px;
}

/* On applique les styles au wrapper intérieur
 * la hauteur est limitée ici,
 * la largeur doit être un multiple impair de 100%
 * pour pouvoir centrer plus facilement avec une marge négative
 * et on aligne le contenu au milieu. */
.inner-image-wrapper {
  height: 100%;
  margin-left: -100%;
  text-align: center;
  width: 300%;
}

/* Dans ce cas les images sont  verticales, donc on les force en hauteur seulement */
.inner-image-wrapper > img {
  height: 100%;
  width: auto;
}

Une fois les styles appliqués, on obtient l'apparence suivante :

Et voilà !

Bon, bien entendu, il ne faut avoir des ratios assez proches les uns des autres, mais ça peut aider dans certains cas courants, et c'est quand même mieux que de recadrer toutes les images dans un logiciel de retouche d'images ou en forçant les dimensions, au risque d'avoir une image complètement écrasée.