web-dev-qa-db-fra.com

Flexbox image échelle à la hauteur et garder les proportions

J'ai un DIV qui est mis à l'échelle à la hauteur disponible en utilisant flexbox CSS. Dans cette DIV est une image que je voudrais mettre à l'échelle avec la DIV dans les deux dimensions. Cela signifie qu'il doit être mis à l'échelle en conservant son format d'image et que les dimensions inférieures à la dimension DIV respective doivent être centrées. 

Je peux faire en sorte que l'image suive la largeur de la DIV, mais pas la hauteur. Par conséquent, les images de portrait s'échappent des limites de la DIV. 

Voici un jsFiddle pour démontrer le problème.

html, body {
  height: 100%;
  margin: 0;
}
.container {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.box {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box img {
  width: auto;
  height: auto;
  max-width: 90%;
  max-height: 90%;
}
<div class="container">
  <div class="box"></div>
  <div class="box" style="background: pink;">
    <img src="//dummyimage.com/300" />
  </div>
  <div class="box"></div>
</div>

17
languitar

si vous pouvez changer de flex en block:

https://jsfiddle.net/svArtist/ug6eoxfs/

comme l'a souligné @janfoeh, utiliser object-fit: contenir permet:

body, html {
    height: 100%;
    margin: 0;
    padding: 0;
    overflow:hidden;
    position:relative;
}

.container {
    width: 100%;
    max-width: 100%;
    height: 100%;
    max-height: 100%;
}

.box {
    background: yellow;
    width: 100%;
    padding: 0 5%;
    box-sizing:border-box;
    max-width: 100%;
    height: 100%;
    max-height:100%;
    position:relative;
}

.box img {
    height:100%;
    max-height: 100%;
    width: auto;
    max-width: 100%;
    margin: auto;
    position:absolute;
    top:0%;
    bottom:0%;
    left:0%;
    right:0%;
    display:block;
    object-fit: contain;
}

Si la mise en page Flex est nécessaire, vous pouvez, en dernier recours, utiliser une image d'arrière-plan, ce qui facilite grandement les choses: https://jsfiddle.net/svArtist/e1c2tLme/

    background: url(http://placehold.it/300) no-repeat center center;
    background-size: contain;

Autre que cela, je ne peux pas trouver un moyen qui n'implique pas de script.

6
Ben Philipp

Lorsque vous spécifiez la hauteur sous forme de pourcentage, il s'agit d'un pourcentage par rapport à la hauteur de l'élément parent. C'est également vrai avec la balise <img>.

Dans cet agencement de flexbox de hauteur inconnue, vous pouvez utiliser les astuces position pour que l'image s'adapte à la largeur et à la hauteur de l'élément flex, et utiliser les astuces transform pour faire le centrage.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.box {
  flex: 1 1 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}
.box:nth-child(2) {
  background: pink;
}
.box img {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}
<div class="container">
  <div class="box"></div>
  <div class="box">
    <img src="//dummyimage.com/300" />
  </div>
  <div class="box"></div>
</div>

Vous pouvez également utiliser background image, ce qui peut faciliter les choses. La clé consiste à utiliser la valeur contain. Voir la démo simplifiée ci-dessous.

jsFiddle

html, body {
  height: 100%;
  margin: 0;
}
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.box {
  flex: 1 1 auto;
}
.box:nth-child(2) {
  background: pink url(//dummyimage.com/300) no-repeat center center / contain;
}
<div class="container">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

5
Stickers

Utilise la flexbox! ( JSFiddle )

body, html {
    height: 100%;
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-flow: column;
    width: 100%;
    height: 100%;
}

.box {
    flex: 1 1 auto;
    background: yellow;
    display: flex;
    justify-content: center;
    align-items: stretch;
}

.box img {
    width: 100%;
    object-fit: contain;
}

La clé consiste à utiliser object-fit: contain; pour conserver les proportions, et align-items: stretch; pour s’assurer que l’image n’est pas tronquée à gauche et à droite (s’agit-il d’un bogue?).

2
darrylyeo

Basé sur la réponse @darrylyeo.

.container {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: stretch;

  width: 100%;
  height: 100%;

  border-radius: 4px;
  background-color: hsl(0, 0%, 96%);
}

.box {
  border-radius: 4px;
  display: flex;
}

.box img {
  width: 100%;
  object-fit: contain;
  border-radius: 4px;
}
0
Ukr