web-dev-qa-db-fra.com

Conserver les proportions de l'image lors du changement de hauteur

À l'aide du modèle de boîte flexible CSS, comment puis-je forcer une image à conserver ses proportions?

JS Fiddle: http://jsfiddle.net/xLc2Le0k/2/

Notez que les images s’étirent ou se rétrécissent afin de remplir la largeur du conteneur. C'est bien, mais peut-on également réduire ou réduire la hauteur pour conserver les proportions de l'image?

HTML

<div class="slider">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
    <img src="http://www.placebacon.net/400/300" alt="Bacn">
</div>

CSS

.slider {
    display: flex;
}
.slider img {
    margin: 0 5px;
}
107
coderMe

Pour les balises img, si vous définissez un côté, l'autre côté est redimensionné pour conserver les proportions et, par défaut, les images se développent à leur taille d'origine.

En utilisant ce fait, si vous enveloppez chaque balise img dans une balise div et définissez sa largeur à 100% de la div parent, la hauteur correspondra au rapport hauteur/largeur que vous souhaitez.

http://jsfiddle.net/0o5tpbxg/

* {
    margin: 0;
    padding: 0;
}
.slider {
    display: flex;
}
.slider .slide img {
    width: 100%;
}
62
Muhammad Umer

Pour empêcher les images de s’étirer dans l’un ou l’autre axe à l’intérieur d’un parent flexible, j'ai trouvé plusieurs solutions.

Vous pouvez essayer d’utiliser objet-fit sur l’image qui, par exemple,.

object-fit: contain;

http://jsfiddle.net/ykw3sfjd/

Ou vous pouvez ajouter des règles flex-specfic qui peuvent fonctionner mieux dans certains cas.

align-self: center;
flex: 0 0 auto;
57
Matty Balaam

Pas besoin d'ajouter un div contenant.

La valeur par défaut de la propriété css "align-items" est "stretch", ce qui a pour effet d'étirer vos images à leur hauteur d'origine. Définir la propriété css "align-items" sur "flex-start" corrige votre problème.

.slider {
    display: flex;
    align-items: flex-start;  /* ADD THIS! */
}
47
Marvin Herbold

La plupart des images avec des dimensions intrinsèques , c'est-à-dire une taille naturelle, comme une image jpeg. Si la taille spécifiée définit à la fois la largeur et la hauteur, la valeur manquante est déterminée à l'aide du rapport intrinsèque ... - voir MDN .

Mais cela ne fonctionne pas comme prévu si les images définies en tant qu’éléments de flex direct avec l’actuel module de disposition de boîte flexible de niveau 1 , autant que je sache.

Voir ces discussions et les rapports de bugs peuvent être liés:

  • Flexbugs # 14 - Le dimensionnement intrinsèque de Chrome/Flexbox n'est pas implémenté correctement.
  • Firefox Bug 972595 - Les conteneurs Flex doivent utiliser "flex-based" au lieu de "width" pour calculer les largeurs intrinsèques des éléments flex
  • Chromium Issue 249112 - Dans Flexbox, autorisez les rapports de format intrinsèques pour éclairer le calcul de la taille principale.

Pour contourner le problème, vous pouvez envelopper chaque <img> avec un <div> ou un <span>, ou presque.

jsFiddle

.slider {
  display: flex;
}

.slider>div {
  min-width: 0; /* why? see below. */
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
<div class="slider">
  <div><img src="https://picsum.photos/400/300?image=0" /></div>
  <div><img src="https://picsum.photos/400/300?image=1" /></div>
  <div><img src="https://picsum.photos/400/300?image=2" /></div>
  <div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>

4.5 Taille minimale implicite des éléments Flex

Pour fournir une taille minimale par défaut plus raisonnable pour éléments flexibles , cette spécification introduit une nouvelle valeur auto en tant que valeur initiale de min-width et min-height propriétés définies dans CSS 2.1.


Alternativement, vous pouvez utiliser CSS table layout à la place. Vous obtiendrez des résultats similaires à flexbox, cela fonctionnera avec davantage de navigateurs, même pour IE8.

jsFiddle

.slider {
  display: table;
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.slider>div {
  display: table-cell;
  vertical-align: top;
}

.slider>div>img {
  max-width: 100%;
  height: auto;
}
<div class="slider">
  <div><img src="https://picsum.photos/400/300?image=0" /></div>
  <div><img src="https://picsum.photos/400/300?image=1" /></div>
  <div><img src="https://picsum.photos/400/300?image=2" /></div>
  <div><img src="https://picsum.photos/400/300?image=3" /></div>
</div>
35
Stickers

Ces derniers temps, je jouais à flexbox et j’ai trouvé une solution à ce problème grâce à l’expérimentation et au raisonnement suivant. Cependant, en réalité, je ne sais pas si c'est exactement ce qui se passe.

Si la largeur réelle est affectée par le système flex. Ainsi, après que la largeur des éléments ait atteint la largeur maximale du parent, la largeur supplémentaire définie dans css est ignorée. Ensuite, il est prudent de régler la largeur à 100%.

Étant donné que la hauteur de la balise img est dérivée de l'image elle-même, définir la hauteur sur 0% peut faire quelque chose. (c'est là que je ne sais pas trop quoi ... mais cela me semblait logique de le réparer)

DÉMO

(rappelez-vous vu ici d'abord!)

.slider {
    display: flex;
}
.slider img {
    height: 0%;
    width: 100%;
    margin: 0 5px;
}

Fonctionne uniquement dans chrome pour le moment

5
Muhammad Umer

Ce comportement est attendu. Le conteneur flex étendra tous les enfants par défaut. Les images ne font pas exception. (Par exemple, le parent aura la propriété align-items: stretch)

Pour conserver les proportions, nous avons deux solutions:

  1. Remplacez la propriété par défaut align-items: stretch par align-items: flex-start ou align-self: center etc, http://jsfiddle.net/e394Lqnt/3/

ou

  1. Définissez la propriété align exclusivement avec l'enfant comme: align-self: center ou align-self: flex-start etc. http://jsfiddle.net/e394Lqnt/2/
1
Asim K T