Flexbox a cassé mes images responsive !

En plein tests de mise en page Responsive, et encore tout excité de pouvoir enfin appliquer Flexbox en production, vous serez surpris de constater un phénomène étrange lorsque vous tenterez d’utiliser la célèbre technique suivante pour rendre vos images fluides à l’intérieur de leur parent :

img {
max-width: 100%;
height: auto;
}

Non seulement, l’image ne s’adapte pas à la taille de son parent comme vous l’aviez prévu, mais pire : c’est son parent qui s’adapte aux dimensions initiales de l’image !

Capture d’écran 2015-10-30 à 20.20.33

Il ne s’agit (malheureusement) pas d’un bug mais de l’observation stricte des récentes spécifications de Flexbox.

Pour rappel, les flex-items ont dorénavant par défaut une valeur de min-width (et min-height) définie à « auto », c’est à dire la taille de leur contenu.

Les spécifications sont claires sur ce point : http://www.w3.org/TR/css-flexbox-1/#min-size-auto
Certains éléments dits « remplacés », c’est à dire les éléments img, video, picture, canvas, textarea, input, etc. possèdent des dimensions intrinsèques.

Prenez le cas suivant :

  • j’ai une image qui doit être fluide
  • cette image est contenue dans un parent qui est un flex-item
  • ce parent est lui-même dans un conteneur flex-container (display: flex)

Le parent flex-item en vertu de sa nouvelle valeur de min-width, calcule sa taille en fonction de cette dimension par défaut, et c’est pourquoi max-width : 100% n’aura aucun effet… puisque c’est l’image elle-même qui détermine la taille de son parent.

Il existe trois méthodes simples pour éviter ce piège et rendre nos images fluides :

  1. min-width: 0; min-height: 0; sur le flex-item (ici le parent de l’image).

    En effet, muni d’une valeur explicite de min-width/height, il n’adopte plus la valeur par défaut « auto », problématique.

  2. flex-direction : column sur le flex-container (ici le grand-parent).

    En basculant dans un axe vertical, c’est la hauteur minimum (min-height) qui est alors calculée en fonction du contenu et non plus la largeur.

  3. EDIT : overflow: hidden (ou auto ou scroll) sur le flex-item (merci Jonathan).

Vous pouvez tester en live ici (pour l’instant, seul Firefox respecte la spec… et donc pose un problème) :

6 réflexions au sujet de « Flexbox a cassé mes images responsive ! »

    1. Je pense qu’il est difficile de gérer ce genre de cas particuliers via un « framework » (tu as quand-même attendu 2015 pour tomber dessus ;)).
      Tant qu’on est dans les replaced elements, sais-tu qu’il n’est actuellement pas possible de rendre un button ou un fieldset (par ex.) en display: flex ?🙂

  1. Merci pour cette petite astuce🙂.

    J’ai été confronté à ce problème il n’y a pas si longtemps et je suis tombé sur le « min-width: 0 » sans trop savoir pourquoi ça marchait ! Dans mes souvenirs il me semble que l’overflow: hidden marchait aussi sur le flex-item ? Il faudrait que je retest.

    J’ai découvert les « replaced elements » et leurs comportements étranges il y a 2 ans. Mon bug concernait la surcharge d’un élément input avec la propriété « display: block ». J’ai du bloquer 2 jours pour comprendre pourquoi l’input ne voulait pas s’étendre à 100% comme tout élément block qui se respecte xD.

Les commentaires sont fermés.