Comment puis-je remplir un div avec une image tout en le gardant proportionnel?

120

J'ai trouvé ce fil - Comment étirer une image pour remplir une <div> tout en conservant le rapport hauteur / largeur de l'image? - ce n'est pas tout à fait ce que je veux.

J'ai un div avec une certaine taille et une image à l'intérieur. je veux toujours remplir le div avec l'image, que l'image soit en mode paysage ou portrait. Et peu importe si l'image est coupée (le div lui-même a le débordement caché).

Donc, si l'image est portrait, je veux widthqu'elle soit 100%et height:autoainsi elle reste proportionnée. Si l'image est en paysage, je veux heightqu'elle soit 100%et que l' width to beauto`. Cela semble compliqué, non?

<div class="container">
   <img src="some-image.jpg" alt="Could be portrait or landscape"/>
</div>

Comme je ne sais pas comment faire, j'ai simplement créé une image rapide de ce que je veux dire. Je ne peux même pas le décrire correctement.

entrez la description de l'image ici

Donc, je suppose que je ne suis pas le premier à poser cette question. Cependant, je n'ai pas vraiment trouvé de solution à cela. Il y a peut-être une nouvelle façon CSS3 de faire cela - je pense à flex-box. Une idée? Peut-être que c'est encore plus facile que ce à quoi je m'attendais?

mat
la source
Pourquoi voulez-vous utiliser css3 alors que vous pouvez toujours le faire facilement avec javascript? Allez avec js matey ..
GautamJeyaraman
1
Non testé, mais vous pouvez essayer de définir la hauteur min et la largeur min à 100%? Cela devrait au moins remplir la boîte et la garder en proportion
chrisbulmer

Réponses:

150

Si je comprends correctement ce que vous voulez, vous pouvez laisser les attributs de largeur et de hauteur hors de l'image pour conserver les proportions et utiliser flexbox pour effectuer le centrage à votre place.

.fill {
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden
}
.fill img {
    flex-shrink: 0;
    min-width: 100%;
    min-height: 100%
}
<div class="fill">
    <img src="https://lorempizza.com/320/240" alt="" />
</div>

JSFiddle ici

J'ai testé cela avec succès dans IE9, Chrome 31 et Opera 18. Mais aucun autre navigateur n'a été testé. Comme toujours, vous devez tenir compte de vos besoins d'assistance particuliers.

Isius
la source
Dans IE9, l'image n'est pas centrée verticalement ou horizontalement avec cette méthode, elle est alignée en haut et à gauche. i59.tinypic.com/ouo77s.png
Mike Kormendy
1
Cela pose un problème sur iPad, il semble que safari étire l'image à 100% de sa hauteur mais ne conserve pas la propriété min-width.
Sean
14
Cela semble redimensionner les petites images pour les remplir, mais pas pour les ajuster. Au moins, lorsque j'utilise une grande image, elle n'en montre qu'une infime partie.
Johncl
12
Pour avoir une grande image à l'échelle, j'ai utilisé ce qui suit sur l'image:.fill img { min-height:100%; min-width: 100%; object-fit: cover; }
Peter G
super héros! : D
Garis M Suero
47

Il est un peu tard, mais j'ai juste eu le même problème et je l'ai finalement résolu avec l'aide d'un autre post stackoverflow ( https://stackoverflow.com/a/29103071 ).

.img {
   object-fit: cover;
   width: 50px;
   height: 100px;
}

J'espère que cela aide encore quelqu'un.

Ps: Fonctionne également avec les propriétés css max-height , max-width , min-width et min-height . Il est particulièrement pratique d'utiliser des unités de longueur comme 100% ou 100vh / 100vw pour remplir le conteneur ou toute la fenêtre du navigateur.

Hermilton
la source
est-ce une solution crossbrowser?
candlejack
1
ajustement de l'objet: couverture; fonctionne très bien! Informations sur le navigateur (ne fonctionne pas dans IE): css-tricks.com/almanac/properties/o/object-fit Solution de secours pour IE: medium.com/@primozcigler / ... MS travaille sur sa mise en œuvre: developer.microsoft.com / fr-us / microsoft-edge / platform / status /…
Kaah
Je suppose que l'ajout d'une object-positionrègle à cette classe sera utile ici. Juste un petit mot.
Taha Paksu
8

Une vieille question mais qui mérite une mise à jour car il existe maintenant un moyen.

La bonne réponse basée sur CSS est d'utiliser object-fit: cover, ce qui fonctionne comme background-size: cover. Le positionnement serait pris en charge par l' object-positionattribut, qui par défaut est centré.

Mais il n'y a pas de support pour cela dans les navigateurs IE / Edge, ou Android <4.4.4. De plus, object-positionn'est pas pris en charge par Safari, iOS ou OSX. Les polyfills existent, les images ajustées aux objets semblent offrir le meilleur support.

Pour plus de détails sur le fonctionnement de la propriété, consultez l' article CSS Tricks surobject-fit pour obtenir des explications et une démonstration.

holiste
la source
8

Cela devrait le faire:

img {    
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
}
maksim1
la source
Fonctionne plutôt bien pour moi, dans mon cas, il me fallait juste ajouter la position: absolue et top: 0, ainsi que quelques z-index
byroncorrales
7

Toutes les réponses ci-dessous ont une largeur et une hauteur fixes, ce qui rend la solution «non réactive».

Pour obtenir le résultat mais garder l'image réactive, j'ai utilisé ce qui suit:

  1. À l'intérieur du conteneur, placez une image gif transparente avec la proportion souhaitée
  2. Donnez un arrière-plan css en ligne à une balise d'image avec l'image que vous souhaitez redimensionner et rogner

HTML:

<div class="container">
    <img style="background-image: url("https://i.imgur.com/XOmNCwY.jpg");" src="img/blank.gif">
</div> 


.container img{
   width: 100%;
   height: auto;
   background-size: cover;
   background-repeat: no-repeat;
   background-position: center;
}​
Artur Klassen
la source
J'ai utilisé l'image de fond pour l'ensemble du site Web de ma société de portefeuille de conception afin que je puisse avoir une taille de fond: couverture. Maintenant, mon référencement d'image est tout gâché car les images d'arrière-plan ne sont pas reconnues par Google. J'aurais aimé l'avoir codé d'une autre manière.
Alex Banman
5

Vous pouvez y parvenir en utilisant les propriétés css flex. Veuillez consulter le code ci-dessous

.img-container {
  border: 2px solid red;
  justify-content: center;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  
}
.img-container .img-to-fit {
  flex: 1;
  height: 100%;
}
<div class="img-container">
  <img class="img-to-fit" src="https://images.pexels.com/photos/8633/nature-tree-green-pine.jpg" />
</div>

Sandeep K Nair
la source
1
Cela fonctionne UNIQUEMENT si vous supprimez les propriétés de largeur et de hauteur évoquées dans certaines des autres réponses.
Chiwda
3

Pensez à utiliser background-size: cover(IE9 +) en conjonction avec background-image. Pour IE8-, il existe un polyfill .

Marat Tanalin
la source
Cela ne nécessite-t-il pas une URL de fond? Pouvez-vous en dire plus? Cela peut-il fonctionner avec <img src = "" /> comme indiqué dans la question?
harsimranb
@harsimranb Bien sûr, cela n'a de background-sizesens qu'avec background-imagespécifié aussi (j'ai mis à jour ma réponse en conséquence). Cela ne s'applique pas aux IMGéléments.
Marat Tanalin
C'est la meilleure réponse. Il est simple et prend en charge le navigateur. Toutes les autres solutions sont soit très complexes, soit ne fonctionnent pas dans IE (9).
JoostS
1

Essaye ça:

img {
  position: relative;
  left: 50%;
  min-width: 100%;
  min-height: 100%;
  transform: translateX(-50%);
}

J'espère que cela t'aides

Landerqvist
la source
1

Vous pouvez utiliser div pour y parvenir. sans balise img :) j'espère que cela vous aidera.

.img{
	width:100px;
	height:100px;
	background-image:url('http://www.mandalas.com/mandala/htdocs/images/Lrg_image_Pages/Flowers/Large_Orange_Lotus_8.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
.img1{
	width:100px;
	height:100px;
	background-image:url('https://images.freeimages.com/images/large-previews/9a4/large-pumpkin-1387927.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
<div class="img">	
</div>
<div class="img1">	
</div>

Sivasakthivel Kalaiarasu
la source
1

La seule façon dont j'ai réalisé le scénario du «meilleur des cas» décrit, a été de mettre l'image en arrière-plan:

<div class="container"></div>
.container {
    width: 150px;
    height: 100px;
    background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
    background-size: cover;
    background-repeat: no-repeat;
    background-position: 50% 50%;
}​
David Schumann
la source
1

Voici une réponse avec prise en charge de l'utilisation d'IE object-fitpour ne pas perdre de ratio

Utilisation d'un simple extrait de code JS pour détecter si le object-fitest pris en charge, puis remplacez le imgpar unsvg

//for browsers which doesn't support object-fit (you can use babel to transpile to ES5)

if ('objectFit' in document.documentElement.style === false) {
  document.addEventListener('DOMContentLoaded', () => {
    Array.prototype.forEach.call(document.querySelectorAll('img[data-object-fit]'), image => {
      (image.runtimeStyle || image.style).background = `url("${image.src}") no-repeat 50%/${image.currentStyle ? image.currentStyle['object-fit'] : image.getAttribute('data-object-fit')}`
      image.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='${image.width}' height='${image.height}'%3E%3C/svg%3E`
    })
  })
}
img {
  display: inline-flex;
  width: 175px;
  height: 175px;
  margin-right: 10px;
  border: 1px solid red
}

/*for browsers which support object fit */

[data-object-fit='cover'] {
  object-fit: cover
}

[data-object-fit='contain'] {
  object-fit: contain
}
<img data-object-fit='cover' src='//picsum.photos/1200/600' />
<img data-object-fit='contain' src='//picsum.photos/1200/600' />
<img src='//picsum.photos/1200/600' />


Remarque: il existe également quelques object-fitpolyfills qui ferontobject-fit fonctionneront.

Voici quelques exemples:

dippas
la source
0

Ici vous avez mon exemple de travail. J'ai utilisé une astuce qui consiste à définir l'image comme arrière-plan du conteneur div avec background-size: cover et background-position: center center

J'ai placé l'image avec une largeur: 100% et une opacité: 0 la rendant invisible. Notez que j'affiche mon image uniquement parce que j'ai un intérêt particulier à appeler l'événement de clic enfant.

Veuillez noter que bien que j'utilise angulaire, cela n'a aucune importance.

<div class="foto-item" ng-style="{'background-image':'url('+foto.path+')'}">
    <img class="materialboxed" ng-class="foto.picid" ng-src="{{foto.path}}" style="opacity: 0;filter: alpha(opacity=0);" width="100%" onclick="$('.materialboxed')/>
 </div>
<style>
.foto-item {
height: 75% !important;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow:hidden;
background-size: cover;
background-position: center center;
}
</style>

Le résultat est celui que vous définissez comme optimal dans tous les cas

Noel Carcasses
la source
0

Le CSS object-fit: coveret object-position: left centerles valeurs de propriété résolvent désormais ce problème.

Conception inversée
la source
0

.image-wrapper{
    width: 100px;
    height: 100px;
    border: 1px solid #ddd;
}
.image-wrapper img {
    object-fit: contain;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
}
<div class="image-wrapper">
  <img src="">
</div>

Yaseen
la source
-3

Fixez simplement la hauteur de l'image et indiquez width = auto

img{
    height: 95vh;
    width: auto;
}
Sarthak
la source