Comment étirer une image pour remplir une <div> tout en conservant le rapport hauteur / largeur de l'image?

201

J'ai besoin de faire étirer cette image à la taille maximale possible sans la faire déborder <div>ou biaiser l'image.

Je ne peux pas prédire le rapport hauteur / largeur de l'image, il n'y a donc aucun moyen de savoir s'il faut utiliser:

<img src="url" style="width: 100%;">

ou

<img src="url" style="height: 100%;">

Je ne peux pas utiliser les deux (c.-à-d. Style = "largeur: 100%; hauteur: 100%;") car cela étirera l'image pour l'adapter à <div>.

Le <div>a une taille définie en pourcentage de l'écran, ce qui est également imprévisible.

Giffyguy
la source
2
Si vous avez besoin de l'image pour remplir la hauteur ou la largeur aux dimensions correspondantes de la div, je ne peux penser qu'à utiliser javascript. Est-ce quelque chose que vous souhaitez explorer?
okw

Réponses:

189

Mise à jour 2016:

Le navigateur moderne se comporte beaucoup mieux. Tout ce que vous devez faire est de régler la largeur de l'image à 100% ( démo )

.container img {
   width: 100%;
}

Puisque vous ne connaissez pas le rapport hauteur / largeur, vous devrez utiliser des scripts. Voici comment je le ferais avec jQuery ( démo ):

CSS

.container {
    width: 40%;
    height: 40%;
    background: #444;
    margin: 0 auto;
}
.container img.wide {
    max-width: 100%;
    max-height: 100%;
    height: auto;
}
.container img.tall {
    max-height: 100%;
    max-width: 100%;
    width: auto;
}​

HTML

<div class="container">
 <img src="http://i48.tinypic.com/wrltuc.jpg" />
</div>
<br />
<br />
<div class="container">
 <img src="http://i47.tinypic.com/i1bek8.jpg" />
</div>

Scénario

$(window).load(function(){
 $('.container').find('img').each(function(){
  var imgClass = (this.width/this.height > 1) ? 'wide' : 'tall';
  $(this).addClass(imgClass);
 })
})
Mottie
la source
L'utilisateur peut-il voir l'image avant le redimensionnement? Quelqu'un l'a testé?
RayLoveless
La solution est presque juste, il suffit d'inverser la hauteur et la largeur dans le CSS: si l'image est `` haute '', alors la largeur doit être à 100% et non la hauteur (qui sera plus grande et débordante). L'inverse pour les photos larges.
mbritto
@mbritto: Vous avez raison, j'ai dû changer le css en max-width / height et j'ai ajouté une démo
Mottie
@Mottie est là un moyen d'adapter une image de largeur 930 px à un conteneur de 960 px sans perdre la qualité de l'image
Vivek Dragon
15
Pourquoi est-ce la réponse acceptée. La question concerne les images trop petites pour leur conteneur. c'est-à-dire comment une image peut-elle être agrandie pour remplir la largeur ou la hauteur de son contenant, sans tromper le rapport hauteur / largeur de l'image. De plus, dans votre démo, la suppression des propriétés width:autoou height:auton'affecte pas l'affichage de vos images. En fait, de toutes les propriétés que vous appliquez à l'image, cela max-width: 100%n'a aucun effet, et cela n'affecte que l'image du paysage. Mais surtout, votre réponse n'aide pas à étirer une petite image pour remplir un plus grand récipient.
matty
78

Il existe un moyen beaucoup plus simple de le faire en utilisant uniquement CSSet HTML:

HTML:

<div class="fill"></div>

CSS:

.fill {
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-image: url('path/to/image.jpg');
}

Cela placera votre image comme arrière-plan et l'étirera pour l'adapter à la divtaille sans distorsion.

Ryan
la source
est-ce possible avec un nombre d'images non défini?
TrtG
background-size: cover;est la vraie magie ici, et c'est CSS3 mais a un support de navigateur raisonnable sur les versions les plus récentes (voir: w3schools.com/cssref/css3_pr_background-size.asp )
Jon Kloske
1
Il pourrait être utile d'inclure l'URL de l'image dans le HTML, afin de séparer le style et le contenu, c'est<div style="background-image: url('path/to/image.jpg');" class="fill"></div>
binaryfunt
background-size: cover ne conserve pas le rapport hauteur / largeur, les parties de l'image qui ne sont pas proportionnelles à l'élément sont rognées. Reportez-vous ici
Alex_Zhong
@Alex_Zhong, vous vous méprenez sur les proportions. Le rapport d'aspect signifie que l'image n'est étirée dans aucune direction (donc un cercle parfait ne deviendrait pas un ovale en largeur ou en hauteur). Le recadrage peut être une partie nécessaire du maintien du rapport hauteur / largeur (comme dans le cas d'utilisation de l'OP).
Jeremy Moritz
70

Pas une solution parfaite, mais ce CSS pourrait aider. Le zoom est ce qui fait que ce code fonctionne, et le facteur devrait théoriquement être infini pour fonctionner idéalement pour les petites images - mais 2, 4 ou 8 fonctionnent très bien dans la plupart des cas.

#myImage {
    zoom: 2;  //increase if you have very small images

    display: block;
    margin: auto;

    height: auto;
    max-height: 100%;

    width: auto;
    max-width: 100%;
}
Prouda
la source
1
Je souhaite que cela fonctionne dans Firefox. Pourquoi pas d' zoomamour de Firefox!?
matty
1
Firefox n'a toujours pas été zoomimplémenté, mais voici le lien de bogue pour référence future: bugzilla.mozilla.org/show_bug.cgi?id=390936
Adam Taylor
31

Si vous le pouvez, utilisez des images d'arrière-plan et définissez background-size: cover . Cela fera que l'arrière-plan couvrira tout l'élément.

CSS

div {
  background-image: url(path/to/your/image.png);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
}

Si vous êtes coincé avec l'utilisation d'images en ligne, il existe quelques options. Tout d'abord, il y a

ajustement aux objets

Cette propriété agit sur les images, vidéos et autres objets similaires à background-size: cover .

CSS

img {
  object-fit: cover;
}

Malheureusement, la prise en charge du navigateur n'est pas terrible avec IE jusqu'à la version 11 qui ne la prend pas en charge du tout. L'option suivante utilise jQuery

CSS + jQuery

HTML

<div>
  <img src="image.png" class="cover-image">
</div>

CSS

div {
  height: 8em;
  width: 15em;
}

Douane Plugin jQuery

(function ($) {
  $.fn.coverImage = function(contain) {
    this.each(function() {
      var $this = $(this),
        src = $this.get(0).src,
        $wrapper = $this.parent();

      if (contain) {
        $wrapper.css({
          'background': 'url(' + src + ') 50% 50%/contain no-repeat'
        });
      } else {
        $wrapper.css({
          'background': 'url(' + src + ') 50% 50%/cover no-repeat'
        });
      }

      $this.remove();
    });

    return this;
  };
})(jQuery);

Utilisez le plugin comme celui-ci

jQuery('.cover-image').coverImage();

Il prendra une image, la définira comme image d'arrière-plan sur l'élément wrapper de l'image et supprimera le img balise du document. Enfin, vous pouvez utiliser

CSS pur

Vous pouvez l'utiliser comme solution de rechange. L'image s'agrandira pour couvrir son conteneur, mais elle ne diminuera pas.

CSS

div {
  height: 8em;
  width: 15em;
  overflow: hidden;
}

div img {
  min-height: 100%;
  min-width: 100%;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  display: block;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

J'espère que cela pourrait aider quelqu'un, codage heureux!

Daniels
la source
Je cherchais une solution CSS pure pour que les images remplissent un conteneur donné sans utiliser background-image & background-size et le code CSS ici fonctionne très bien pour> = IE9 et les navigateurs modernes. Démo CodePen ici
FLOQ Design
En Pure CSS , j'ai supprimé min-et modifié width: 100%; height: 100%;et travaillé! solution géniale! +1 Merci!
Guilherme Nascimento
1
background-size: containest également utile si vous souhaitez qu'aucune image ne soit jamais écrêtée.
Ponkadoodle
Vous pouvez ajouter zoom:0.001à la solution Pure CSS pour réduire.
Ivor Zhou
12

Mise à jour 2019.

Vous pouvez maintenant utiliser la object-fitpropriété css qui accepte les valeurs suivantes:fill | contain | cover | none | scale-down

https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

Par exemple, vous pourriez avoir un conteneur contenant une image.

<div class="container">
    <img src="" class="container_img" />
</div>

.container {
    height: 50px;
    width: 50%;

.container_img {
    height: 100%;
    width: 100%;
    object-fit: cover;
Ed Stennett
la source
7

C'est impossible avec juste HTML et CSS, ou du moins follement exotique et compliqué. Si vous êtes prêt à ajouter du javascript, voici une solution utilisant jQuery:

$(function() {
    $(window).resize(function() {
        var $i = $('img#image_to_resize');
        var $c = $img.parent();
        var i_ar = $i.width() / $i.height(), c_ar = $c.width() / $c.height();            
        $i.width(i_ar > c_ar ? $c.width() : $c.height() * (i_ar));
    });
    $(window).resize();
});

Cela redimensionnera l'image afin qu'elle tienne toujours à l'intérieur de l'élément parent, quelle que soit sa taille. Et comme il est lié à l' $(window).resize()événement, lorsque l'utilisateur redimensionne la fenêtre, l'image s'ajuste.

Cela n'essaie pas de centrer l'image dans le conteneur, ce serait possible mais je suppose que ce n'est pas ce que vous recherchez.

Tatu Ulmanen
la source
4
Je suppose que $ img.parent (); devrait vraiment être $ i.parent ();
Jimbo Jonny
5

Réglez la largeur et la hauteur du containerdiv extérieur . Ensuite, utilisez le style ci-dessous sur img:

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

Cela vous aidera à garder un rapport d'aspect de votre img

Chintan Bhatt
la source
6
il ne remplira pas le div.
Sven van den Boogaart
5

Si vous souhaitez définir une largeur ou une hauteur maximale (afin qu'elle ne soit pas très grande) tout en conservant le rapport hauteur / largeur des images, vous pouvez le faire:

img{
   object-fit: contain;
   max-height: 70px;
}
Bohao LI
la source
4

Je suis tombé sur cette question à la recherche d'un problème similaire. Je crée une page Web avec un design réactif et la largeur des éléments placés sur la page est définie sur un pourcentage de la largeur de l'écran. La hauteur est définie avec une valeur vw.

Puisque j'ajoute des articles avec PHP et un backend de base de données, le CSS pur était hors de question. Cependant, j'ai trouvé la solution jQuery / javascript un peu difficile, alors j'ai trouvé une solution soignée (donc je me pense au moins).

HTML (ou php)

div.imgfill {
  float: left;
  position: relative;
  background-repeat: no-repeat;
  background-position: 50%  50%;
  background-size: cover;
  width: 33.333%;
  height: 18vw;
  border: 1px solid black; /*frame of the image*/
  margin: -1px;
}
<div class="imgfill" style="background-image:url(source/image.jpg);">
  This might be some info
</div>
<div class="imgfill" style="background-image:url(source/image2.jpg);">
  This might be some info
</div>
<div class="imgfill" style="background-image:url(source/image3.jpg);">
  This might be some info
</div>

En utilisant style = "", il est possible que PHP mette à jour ma page dynamiquement et le style CSS avec style = "" se retrouvera dans une image parfaitement couverte, mise à l'échelle pour couvrir la balise div dynamique.

Christian Jensen
la source
4

Pour étirer cette image à la taille maximale possible sans déborder ni l'incliner.

Appliquer...

img {
  object-fit: cover;
  height: -webkit-fill-available;
}

styles à l'image.

ianbeans
la source
3

En utilisant cette méthode, vous pouvez remplir votre div avec le rapport variable d'image des divs et des images.

jQuery:

$(window).load(function(){
   $('body').find(.fillme).each(function(){
      var fillmeval = $(this).width()/$(this).height();
      var imgval = $this.children('img').width()/$this.children('img').height();
      var imgClass;
      if(imgval > fillmeval){
          imgClass = "stretchy";
      }else{
          imgClass = "stretchx";
      }
      $(this).children('img').addClass(imgClass);
   });
});

HTML:

<div class="fillme">
   <img src="../images/myimg.jpg" />
</div>

CSS:

.fillme{
  overflow:hidden;
}
.fillme img.stretchx{
  height:auto;
  width:100%;
}
.fillme img.stretchy{
  height:100%;
  width:auto;
}
user1994142
la source
3

Cela a fait l'affaire pour moi

div img {
    width: 100%;
    min-height: 500px;
    width: 100vw;
    height: 100vh;
    object-fit: cover;
}
Developer_D
la source
2

si vous travaillez avec le tag IMG, c'est facile.

J'ai fabriqué ça:

<style>
        #pic{
            height: 400px;
            width: 400px;
        }
        #pic img{
            height: 225px;               
            position: relative;
            margin: 0 auto;
        }
</style>

<div id="pic"><img src="images/menu.png"></div>

$(document).ready(function(){
            $('#pic img').attr({ 'style':'height:25%; display:none; left:100px; top:100px;' })
)}

mais je n'ai pas trouvé comment le faire fonctionner avec #pic {background: url (img / menu.png)} Enyone? Merci

aleXela
la source
fait un changement et trouvé une réponse à mon problème! Non, cela aidera quelqu'un. background-image: url (images / menu.png); background-repeat: pas de répétition; position: absolue; taille d'arrière-plan: 300px; hauteur: 100%; largeur: 100%; et vous pouvez modifier la valeur de la taille d'arrière-plan en utilisant javascript ou jquery (.attr ({'style': 'background-size: 150px auto; left: 50px; top: 50px;'}))
aleXela
2

J'ai eu un problème similaire. Je l'ai résolu avec seulement CSS .

Fondamentalement Object-fit: cover vous aide à réaliser la tâche de maintenir le rapport d'aspect tout en positionnant une image à l'intérieur d'un div.

Mais le problème était Object-fit: cover ne fonctionnait pas dans IE et il prenait 100% de largeur et 100% de hauteur et le rapport d'aspect était déformé. En d'autres termes, l'effet de zoom d'image n'était pas là, ce que je voyais en chrome.

L'approche que j'ai prise était de positionner l'image à l'intérieur du conteneur avec de l' absolu puis de la placer directement au centre en utilisant la combinaison:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Une fois au centre, je donne à l'image,

// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;

// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;

Cela donne à l'image l'effet de l'ajustement d'objet: couverture.


Voici une démonstration de la logique ci-dessus.

https://jsfiddle.net/furqan_694/s3xLe1gp/

Cette logique fonctionne dans tous les navigateurs.

Furqan Rahamath
la source
1

HTML:

<style>
#foo, #bar{
    width: 50px; /* use any width or height */
    height: 50px;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
}
</style>

<div id="foo" style="background-image: url('path/to/image1.png');">
<div id="bar" style="background-image: url('path/to/image2.png');">

JSFiddle

... Et si vous souhaitez définir ou modifier l'image (en utilisant #foo comme exemple):

jQuery:

$("#foo").css("background-image", "url('path/to/image.png')");

JavaScript:

document.getElementById("foo").style.backgroundImage = "url('path/to/image.png')";
Patch92
la source
1

La plupart des solutions trouvées ici ont certaines limites: certaines ne fonctionnent pas dans IE (object-fit) ou dans des navigateurs plus anciens, d'autres solutions ne mettent pas à l'échelle les images (les rétrécissent uniquement), de nombreuses solutions ne prennent pas en charge le redimensionnement de la fenêtre et beaucoup le sont non générique, attendez-vous à une résolution ou à une mise en page fixes (portrait ou paysage)

Si l'utilisation de javascript et de jquery n'est pas un problème, j'ai cette solution basée sur le code de @Tatu Ulmanen. J'ai corrigé quelques problèmes et ajouté du code au cas où l'image serait chargée de manière dynamique et ne serait pas disponible au début. Fondamentalement, l'idée est d'avoir deux règles CSS différentes et de les appliquer si nécessaire: une lorsque la limitation est la hauteur, nous devons donc afficher des barres noires sur les côtés, et l'autre règle CSS lorsque la limitation est la largeur, nous devons donc afficher des barres noires en haut / en bas.

function applyResizeCSS(){
    var $i = $('img#imageToResize');
    var $c = $i.parent();
    var i_ar = Oriwidth / Oriheight, c_ar = $c.width() / $c.height();  
    if(i_ar > c_ar){
        $i.css( "width","100%");
        $i.css( "height","auto");          
    }else{
        $i.css( "height","100%");
        $i.css( "width","auto");
    }
}   
var Oriwidth,Oriheight;
$(function() {
    $(window).resize(function() {
        applyResizeCSS();
    });

    $("#slide").load(function(){
        Oriwidth  = this.width,
        Oriheight = this.height; 
        applyResizeCSS();
    }); 

    $(window).resize();
}); 

Pour un élément HTML comme:

<img src="images/loading.gif" name="imageToResize" id="imageToResize"/> 
jolumg
la source