Redimensionner automatiquement l'image dans la mise en page CSS FlexBox et conserver le rapport hauteur / largeur?

98

J'ai utilisé la disposition de la boîte flexible CSS qui apparaît comme indiqué ci-dessous:

entrez la description de l'image ici

Si l'écran devient plus petit, il se transforme en ceci:

entrez la description de l'image ici

Le problème est que les images ne sont pas redimensionnées en conservant le rapport hauteur / largeur de l'image d'origine.

Est-il possible d'utiliser du CSS pur et la mise en page de la boîte flexible pour permettre aux images d'être redimensionnées si l'écran devient plus petit?

Voici mon html:

<div class="content">
  <div class="row"> 
    <div class="cell">
      <img src="http://i.imgur.com/OUla6mK.jpg"/>
    </div>
    <div class="cell">
      <img src="http://i.imgur.com/M16WzMd.jpg"/>
    </div>
  </div>
</div>

mon CSS:

.content {
    background-color: yellow;    
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

    background-color: red;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto; 

    padding: 10px;
    margin: 10px;

    background-color: green;
    border: 1px solid red;
    text-align: center;

}
confiler
la source

Réponses:

83

img {max-width:100%;}est une façon de faire cela. Ajoutez-le simplement à votre code CSS.

http://jsfiddle.net/89dtxt6s/

Oméga
la source
3
Est-il également possible de faire cela pour la dimension de hauteur si l'écran devient plus petit?
confilez le
@confile cela dépendrait beaucoup de la disposition de votre code, mais vous pouvez essayer d'ajouter height:100%;au imgcss.
Omega
height: 100vhle ferait, non height: 100%. Le style pour la hauteur est toujours délicat.
gdbj
1
Pourquoi est-ce marqué comme la bonne réponse? Omega ne l'a-t-il pas transformé en comportement par défaut du navigateur? jsfiddle.net/89dtxt6s/221
VeeK
69

Je suis venu ici à la recherche d'une réponse à mes images déformées. Je ne suis pas tout à fait sûr de ce que l'opération recherche ci-dessus, mais j'ai trouvé que l'ajout align-items: centerle résoudrait pour moi. En lisant la documentation, il est logique de remplacer cette align-items: stretchoption si vous fléchissez directement des images, car c'est la valeur par défaut. Une autre solution consiste à envelopper d'abord vos images avec un div.

.myFlexedImage {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
}
gdbj
la source
11
"Je suis venu ici à la recherche d'une réponse à mes images déformées" Je suis arrivé ici pour la même raison et votre solution m'a aidé (ce qui a été marqué comme la solution réelle ne m'a pas aidé du tout)
Wagner da Silva
cela m'a aidé aussi, quelqu'un peut-il expliquer pourquoi cela fonctionne?
Jerry B. n ° 1 stagiaire
C'était la bonne réponse pour moi. largeur max: 100%; n'a pas corrigé la hauteur (la hauteur était encore légèrement étirée). Dans mon cas, j'ai utilisé align-items: flex-start; parce que je ne voulais pas que l'image soit centrée verticalement dans le conteneur, mais cela fonctionnait toujours car il remplace les éléments align-items par défaut: stretch; Voici une liste de toutes les valeurs de propriété pour align-items que vous pouvez utiliser pour remplacer: w3schools.com/cssref/css3_pr_align-items.asp
Kyle Vassella
J'ai essayé beaucoup de choses, mais votre align-items: centrer sur le parent est le seul qui a fait l'affaire.
Micros
Cela devrait être la réponse acceptée. Align-content n'a pas fonctionné pour moi en termes d'étirement, mais align-items, les deux ont des fonctions différentes. Cette SE clarifie la différence entre les deux: stackoverflow.com/questions/27539262/…
John Ernest
41

Vous voudrez peut-être essayer la toute nouvelle et simple fonctionnalité CSS3:

img { 
  object-fit: contain;
}

Il préserve le rapport d'image (comme lorsque vous utilisez l'astuce de l'image d'arrière-plan) et, dans mon cas, a bien fonctionné pour le même problème.

Attention cependant, il n'est pas pris en charge par IE (voir les détails du support ici ).

Lokinou
la source
4
N'oubliez pas que l'objet parent doit être un flex
Lokinou
J'ai essayé cela et cela a parfaitement fonctionné dans une division flex.
Rémy Kaloustian
5

Je suggère d'examiner les background-sizeoptions pour ajuster la taille de l'image.

Au lieu d'avoir l'image dans la page si vous l'avez définie comme image d'arrière-plan, vous pouvez définir:

background-size: contain

ou

background-size: cover

Ces options prennent en compte à la fois la hauteur et la largeur lors de la mise à l'échelle de l'image. Cela fonctionnera dans IE9 et tous les autres navigateurs récents.

user3196436
la source
3

Dans la deuxième image, il semble que vous souhaitiez que l'image remplisse la case, mais l'exemple que vous avez créé conserve le rapport hauteur / largeur (les animaux ont l'air normaux, pas minces ou gros).

Je n'ai aucune idée si vous avez retravaillé ces images à titre d'exemple ou si la seconde est "comment ça devrait être" aussi (vous avez dit IS, tandis que le premier exemple vous avez dit "devrait")

Quoi qu'il en soit, je dois supposer:

Si "les images ne sont pas redimensionnées en conservant le rapport hauteur / largeur" ​​et que vous me montrez une image qui garde le rapport hauteur / largeur des pixels, je dois supposer que vous essayez de réaliser le rapport hauteur / largeur de la zone de "recadrage" (l'intérieur de le vert) WILE en gardant le rapport hauteur / largeur des pixels. C'est-à-dire que vous souhaitez remplir la cellule avec l'image, en agrandissant et en recadrant l'image.

Si c'est votre problème, le code que vous avez fourni ne reflète PAS "votre problème", mais votre exemple de départ.

Compte tenu des deux hypothèses précédentes, ce dont vous avez besoin ne peut pas être accompli avec des images réelles si la hauteur de la boîte est dynamique, mais avec des images d'arrière-plan. Soit en utilisant "background-size: contain" ou ces techniques (rembourrages intelligents en pourcentages qui limitent le recadrage ou tailles max partout où vous le souhaitez): http://fofwebdesign.co.uk/template/_testing/scale-img/scale- img.htm

La seule façon dont cela est possible avec des images est si nous OUBLIONS votre deuxième iimage et que les cellules ont une hauteur fixe, et FORTUNEMENT, à en juger par vos exemples d'images, la hauteur reste la même!

Donc, si la hauteur de votre conteneur ne change pas et que vous voulez garder vos images carrées, il vous suffit de définir la hauteur maximale des images sur cette valeur connue (moins les rembourrages ou les bordures, en fonction de la propriété de taille de la boîte du cellules)

Comme ça:

<div class="content">
  <div class="row">    
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-2.jpg"/>
      </div>
      <div class="cell">    
          <img src="http://lorempixel.com/output/people-q-c-320-320-7.jpg"/>
      </div>
    </div>
</div>

Et le CSS:

.content {
    background-color: green;
}

.row {
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;

    -webkit-box-orient: horizontal; 
    -moz-box-orient: horizontal;
    box-orient: horizontal;
    flex-direction: row;

    -webkit-box-pack: center;
    -moz-box-pack: center;
    box-pack: center;
    justify-content: center;

    -webkit-box-align: center;
    -moz-box-align: center;
    box-align: center;  
    align-items: center;

}

.cell {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    box-flex: 1;
    -webkit-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 10px;
    border: solid 10px red;
    text-align: center;
    height: 300px;
    display: flex;
    align-items: center;
    box-sizing: content-box;
}
img {
    margin: auto;
    width: 100%;
    max-width: 300px;
    max-height:100%
}

http://jsfiddle.net/z25heocL/

Votre code n'est pas valide (les balises d'ouverture sont au lieu de fermer celles, donc elles produisent des cellules NESTED, pas des frères et sœurs, il a utilisé une capture d'écran de vos images à l'intérieur du code défectueux, et la boîte flexible ne contient pas les cellules mais les deux exemples dans une colonne ( vous configurez "row" mais le code corrompu imbriquant une cellule dans l'autre a entraîné un flex à l'intérieur d'un flex, fonctionnant finalement comme COLUMNS. Je n'ai aucune idée de ce que vous vouliez accomplir, et comment vous avez trouvé ce code, mais je ' m deviner ce que vous voulez est ceci.

J'ai ajouté display: flex aux cellules aussi, donc l'image est centrée (je pense qu'elle display: tableaurait pu être utilisée ici aussi avec tout ce balisage)

Sergio
la source
Il ne semble pas que vous ayez la moindre idée de la manière dont j'ai répondu à la question. Tout le HTML et le CSS dans ce jsfiddle est ce que l'interrogateur (@confile) a fourni. Lisez simplement la question et vous verrez cela. Ma solution est une simple ligne de css img {max-width: 100%;} et le questionneur a accepté ma réponse il y a plus d'un an car elle fournit la solution demandée. Je vous souhaite tout le meilleur ici, essayez de lire correctement les questions, puis répondez en conséquence à l'avenir, merci.
Omega
0

HTML:

<div class="container">
    <div class="box">
        <img src="http://lorempixel.com/1600/1200/" alt="">
    </div>
</div>

CSS:

.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;
}
Ukr
la source
0

C'est ainsi que je gérerais différentes images (tailles et proportions) dans une grille flexible.

.images {
  display: flex;
  flex-wrap: wrap;
  margin: -20px;
}

.imagewrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: calc(50% - 20px);
  height: 300px;
  margin: 10px;
}

.image {
  display: block;
  object-fit: cover;
  width: 100%;
  height: 100%; /* set to 'auto' in IE11 to avoid distortions */
}
<div class="images">
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1000x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/500x800" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/800x600" />
  </div>
  <div class="imagewrapper">
    <img class="image" src="https://via.placeholder.com/1024x768" />
  </div>
</div>

ggzone
la source
-5

J'utilise jquery ou vw pour conserver le ratio

jquery

function setSize() {
    var $h = $('.cell').width();
    $('.your-img-class').height($h);
}
$(setSize);
$( window ).resize(setSize); 

vw

 .cell{
    width:30vw;
    height:30vw;
}
.cell img{
    width:100%;
    height:100%;
}
Erick Boileau
la source