CSS force le redimensionnement de l'image et conserve le rapport hauteur / largeur

577

Je travaille avec des images et j'ai rencontré un problème de rapport hauteur / largeur.

<img src="big_image.jpg" width="900" height="600" alt="" />

Comme vous pouvez le voir, heightet widthsont déjà spécifiés. J'ai ajouté une règle CSS pour les images:

img {
  max-width:500px;
}

Mais pour big_image.jpg, je reçois width=500et height=600. Comment définir des images à redimensionner, tout en conservant leurs proportions.

Moonvader
la source

Réponses:

775

img {
  display: block;
  max-width:230px;
  max-height:95px;
  width: auto;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

Cela fera rétrécir l'image si elle est trop grande pour la zone spécifiée (comme inconvénient, cela n'agrandira pas l'image).

setec
la source
11
Existe-t-il une version qui agrandira les images pour qu'elles s'adaptent également à leur conteneur? J'ai essayé le max-width / max-height sous forme de nombres avec largeur / hauteur comme auto, mais comme setec l'a dit ci-dessus, cela n'agrandira pas l'image. J'ai également essayé d'utiliser min-width / min-height. Je n'arrive pas à obtenir la bonne combinaison. Je veux simplement que quelle que soit l'image que je dois mettre dans ce conteneur, elle s'affichera à sa taille maximale possible sans changer le rapport d'aspect, que cela implique de réduire ou d'agrandir l'image pour y parvenir.
Dee2000
7
Semble que l'affichage: le bloc n'est plus nécessaire.
actimel
3
Notez que la question portait sur un <img>qui comprend lui-même une largeur et une hauteur et je pense que cela signifie que vous devez utiliser !importantpour contourner les informations de largeur / hauteur du tag.
Alexis Wilke
18
Les règles CSS @AlexisWilke remplacent les attributs html. !importantn'est pas nécessaire.
Jargs
5
L'utiliser sur Chrome, ne fonctionne pas pour moi, même avec! Important
Ray
266

J'ai eu du mal avec ce problème, et j'ai finalement trouvé cette solution simple:

object-fit: cover;
width: 100%;
height: 250px;

Vous pouvez ajuster la largeur et la hauteur en fonction de vos besoins, et la propriété d'ajustement d'objet fera le recadrage pour vous.

À votre santé.

Théo T. Carranza
la source
44
object-fitest fantastique, super astuce! Il existe de belles bibliothèques polyfill si quelqu'un se pose des questions sur la compatibilité IE.
doucement
7
Charmant, gardez à l'esprit que cela ne fonctionne pas pour IE cependant
guival
1
Non viable sur les WebApps SAMSUNG Signage Display.
Mär
3
Meilleure solution disponible
Cynthia Sanchez
10
Vous pouvez également utiliser object-fit: containet spécifier une largeur ou une hauteur!
Broper
236

Les solutions ci-dessous permettront d'augmenter et de réduire l'échelle de l'image , selon la largeur de la boîte parent.

Toutes les images ont un conteneur parent avec une largeur fixe à des fins de démonstration uniquement . En production, ce sera la largeur de la boîte parent.

Meilleure pratique (2018):

Cette solution indique au navigateur de rendre l'image avec la largeur maximale disponible et d'ajuster la hauteur en pourcentage de cette largeur.

.parent {
  width: 100px;
}

img {
  display: block;
  width: 100%;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
  <img width="400" height="400" src="https://placehold.it/400x400">
</div>

Solution plus sophistiquée:

Avec la solution plus sophistiquée, vous pourrez recadrer l'image quelle que soit sa taille et ajouter une couleur d'arrière-plan pour compenser le recadrage.

.parent {
  width: 100px;
}

.container {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  overflow: hidden;
  padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}

.container img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
  <div class="container">
    <img width="640" height="220" src="https://placehold.it/640x220">
  </div>
</div>

Pour la ligne spécifiant le remplissage, vous devez calculer le rapport d'aspect de l'image, par exemple:

640px (w) = 100%
220px (h) = ?

640/220 = 2.909
100/2.909 = 34.37%

Ainsi, le rembourrage supérieur = 34,37%.

Aternus
la source
1
Il fonctionne, mais devrait avoir une largeur maximale: 100% au lieu de la largeur dans la plupart des utilisations.
Mec du
Je ne pense pas que ce !importantsoit nécessaire ici.
Flimm
1
Avec le parent réglé sur 100px. Comment cela fonctionnera-t-il de manière réactive?
Remi
@Remi à des fins de démonstration. J'ai ajouté une clarification en haut de la réponse.
Aternus
@Flimm, il était utilisé précédemment pour des problèmes de compatibilité, en 2016, ce n'est plus nécessaire.
Aternus
64

La propriété background-size est ie> = 9 seulement, mais si cela vous convient, vous pouvez utiliser un div avec background-imageet définir background-size: contain:

div.image{
    background-image: url("your/url/here");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

Maintenant, vous pouvez simplement définir la taille de votre div à tout ce que vous voulez et non seulement l'image gardera son rapport d'aspect, elle sera également centralisée à la fois verticalement et horizontalement dans le div. N'oubliez pas de définir les tailles sur le CSS, car les divs n'ont pas l'attribut width / height sur la balise elle-même.

Cette approche est différente de la réponse des setecs, en utilisant cela, la zone d'image sera constante et définie par vous (en laissant des espaces vides horizontalement ou verticalement en fonction de la taille div et du rapport hauteur / largeur de l'image), tandis que la réponse des setecs vous donnera une boîte qui exactement taille de l'image mise à l'échelle (sans espaces vides).

Modifier: selon la documentation de taille d'arrière-plan MDN, vous pouvez simuler la propriété de taille d'arrière-plan dans IE8 à l'aide d'une déclaration de filtre propriétaire:

Bien qu'Internet Explorer 8 ne prenne pas en charge la propriété background-size, il est possible d'émuler certaines de ses fonctionnalités à l'aide de la fonction de filtre -ms non standard:

-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";
Hoffmann
la source
2
enfin une solution CSS uniquement pour maximiser une image tout en conservant ses proportions, merci. Heureusement qu'IE avant 9 est de moins en moins important.
humanityANDpeace
2
Excellente solution, merci! Notez également que vous pouvez remplacer «contenir» par «couvrir» si vous souhaitez remplir complètement la division et recadrer des pixels supplémentaires qui ne correspondent pas au rapport
mbritto
Ce devrait être la bonne réponse. J'adore cette solution. Il garde vos proportions et est facile à comprendre.
skolind
1
Bien que ce soit une bonne réponse par programme, si une image «compte» de cette façon, vous n'avez pas d'attributs img et vous tuez le référencement.
fat_mike
Génial! C'était la seule de ces solutions qui fonctionnait à la fois pour les images portrait et paysage ainsi que pour les conteneurs portrait et paysage de l'image (par exemple variant en fonction de la taille de la fenêtre) dans les 4 combinaisons et en plus dans IE11, qui semblait être assez une exigence. Je vous remercie!
cupiqi09
53

Très similaire à certaines réponses ici, mais dans mon cas, j'avais des images qui étaient parfois plus hautes, parfois plus grandes.

Ce style a fonctionné comme un charme pour s'assurer que toutes les images utilisent tout l'espace disponible, gardent le rapport et non les coupes:

.img {
   object-fit: contain;
   max-width: 100%;
   max-height: 100%;
   width: auto;
   height: auto;
}
Moisés
la source
object-fitfonctionne pour moi ça marche dans tous les navigateurs?
Murtuza Zabuawala du
Une .imgclasse est-elle sur le parent ou l'image? Pourriez-vous faire un jsfiddle avec un exemple pour les images portrait et paysage?
Design par Adrian le
19

Supprimez la propriété "height".

<img src="big_image.jpg" width="900" alt=""/>

En spécifiant les deux, vous modifiez le rapport d'aspect de l'image. Le simple fait d'en définir un redimensionnera mais conservera le rapport hauteur / largeur.

Facultativement, pour limiter les surdimensionnements:

<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>
el Dude
la source
je ne peux pas le faire pour toutes les images - il y a beaucoup d'images déjà placées dans de nombreux fichiers html
moonvader
2
D'accord. essayez img {max-width: 500px; hauteur: auto; max-height: 600px;}
el Dude
1
Des informations utiles comme ce commentaire doivent être ajoutées à votre message. De cette façon, nous pouvons immédiatement voir ce que vous avez trouvé.
Bram Vanroy
2
L'inconvénient d'omettre l' heightattribut dans la imgbalise est que le navigateur ne peut pas calculer la quantité d'espace que l'image prendra avant de télécharger l'image. Cela rend la page plus lente à rendre et cela peut conduire à plus de "saut".
Flimm
11

Ajoutez simplement ceci à votre css, il se rétrécira et s'élargira automatiquement en conservant le rapport d'origine.

img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
Mark Bax
la source
2
C'est la même réponse que la réponse de setec , sauf en utilisant 100%au lieu d'une valeur de pixel spécifique.
Flimm
5
display: block;est inutile.
Flimm
C'est parfait et fonctionne avec des images de toutes tailles et proportions
Le Droid
8

Il n’existe aucun moyen standard de conserver le rapport d’aspect des images avec width, heightetmax-width spécifié en même temps.

Nous sommes donc obligés soit de préciser width et heightd’empêcher les sauts de page lors du chargement des images, soit d’utilisermax-width et non de spécifier les dimensions des images.

Spécifier juste width (sans height) n'a généralement pas beaucoup de sens, mais vous pouvez essayer de remplacer l' heightattribut HTML en ajoutant une règle commeIMG {height: auto; } dans votre feuille de style.

Voir aussi le bug Firefox 392261 associé .

Marat Tanalin
la source
merci ça marche dans les versions modernes d'IE, Opera, FF et Chrome. j'ai besoin de temps pour le tester avec d'autres navigateurs.
Moonvader
7
Ne pas utiliser !importanten CSS. C'est un hack qui finira par revenir vous hanter.
Automatico
1
Vous n'avez même pas besoin !importantici.
Flimm
8

Voici une solution:

img {
   width: 100%;
   height: auto;
   object-fit: cover;
}

Cela garantira que l'image couvre toujours l'ensemble du parent (mise à l'échelle vers le bas et vers le haut) et conserve le même rapport hauteur / largeur.

Thomas Carlton
la source
5

Définissez la classe CSS de votre balise de conteneur d'image sur image-class:

<div class="image-full"></div>

et ajoutez ceci à votre feuille de style CSS.

.image-full {
    background: url(...some image...) no-repeat;
    background-size: cover;
    background-position: center center;
}
Aleksandar Toplek
la source
5

Pour conserver une image réactive tout en imposant à l'image un certain rapport d'aspect, vous pouvez effectuer les opérations suivantes:

HTML:

<div class="ratio2-1">
   <img src="../image.png" alt="image">
</div>

Et SCSS:

.ratio2-1 {
  overflow: hidden;
  position: relative;

  &:before {
    content: '';
    display: block;
    padding-top: 50%; // ratio 2:1
  }

  img {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
  }
}

Cela peut être utilisé pour appliquer un certain rapport d'aspect, quelle que soit la taille de l'image que les auteurs téléchargent.

Merci à @Kseso sur http://codepen.io/Kseso/pen/bfdhg . Vérifiez cette URL pour plus de ratios et un exemple de travail.

Rémi
la source
J'aime ça car cela fonctionne avec les cercles / border-radius. Mais malheureusement, cela recadre l'image et ne fait pas si bien avec la création d'une bordure pour l'image dans la div autant que j'ai essayé.
Jake
4

Pour forcer une image qui tient dans une taille exacte, vous n'avez pas besoin d'écrire trop de codes. C'est si simple

img{
    width: 200px;
    height: auto;
    object-fit: contain; /* Fit logo in the image size */
        -o-object-fit: contain; /* Fit logo fro opera browser */
    object-position: top; /* Set logo position */
        -o-object-position: top; /* Logo position for opera browser */
    }
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">

aislamfaisal
la source
4

https://jsfiddle.net/sot2qgj6/3/

Voici la réponse si vous voulez mettre une image avec un pourcentage de largeur fixe , mais pas un pixel de largeur fixe .

Et cela sera utile pour gérer différentes tailles d'écran .

Les astuces sont

  1. Utiliser padding-toppour régler la hauteur à partir de la largeur.
  2. Utiliser position: absolutepour placer l'image dans l'espace de remplissage.
  3. Utilisez max-height and max-widthpour vous assurer que l'image ne dépassera pas l'élément parent.
  4. avec display:block and margin: autopour centrer l'image.

J'ai également commenté la plupart des astuces à l'intérieur du violon.


Je trouve également d'autres moyens d'y parvenir. Il n'y aura pas d'image réelle en html, donc je personnalise personnellement la première réponse quand j'ai besoin de l'élément "img" en html.

css simple en utilisant le fond http://jsfiddle.net/4660s79h/2/

image de fond avec mot en haut http://jsfiddle.net/4660s79h/1/

le concept pour utiliser la position absolue est d'ici http://www.w3schools.com/howto/howto_css_aspect_ratio.asp

Choco Li
la source
Cela ne fonctionne pas si "la hauteur et la largeur sont déjà spécifiées" comme le mentionne la question d'origine. Il y a des moments où vous souhaitez forcer la largeur et la hauteur, puis agrandir / réduire l'image en fonction du rapport d'aspect.
Design par Adrian le
3

Vous pouvez utiliser ceci:

img { 
    width: 500px; 
    height: 600px; 
    object-fit: contain; 
    position: relative; 
    top: 50%; 
    transform: translateY(-50%); 
}
user3334941
la source
2

Vous pouvez créer un div comme ceci:

<div class="image" style="background-image:url('/to/your/image')"></div>

Et utilisez ce CSS pour le styliser:

height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover
Chun Yang
la source
Cela étendra le div à 100% de la largeur de son parent, mais ne conservera pas le rapport d'aspect de l'image.
David Ball
L'avez-vous essayé? Je l'ai fait fonctionner jsfiddle.net/zuysj22w . Pouvez-vous montrer votre cas? @DavidBall
Chun Yang
Il s'agit d'une solution similaire à la réponse de Hoffmann .
Flimm
2

Je suggérerais que pour une approche réactive, la meilleure pratique serait d'utiliser les unités de fenêtre et les attributs min / max comme suit:

img{
  display: block;
  width: 12vw;
  height:12vw;
  max-width:100%;
  min-width:100px;
  min-height:100px;
  object-fit:contain;
}
nodws
la source
1

Cela fera rétrécir l'image si elle est trop grande pour la zone spécifiée (comme inconvénient, cela n'agrandira pas l'image).

La solution de setec est très bien pour "Shrink to Fit" en mode automatique. Mais, pour AGRANDIR de manière optimale pour tenir en mode 'auto', vous devez d'abord mettre l'image reçue dans un identifiant temporaire, vérifiez si elle peut être agrandie en hauteur ou en largeur (en fonction de son rapport d'aspect v / s le rapport d'aspect de votre bloc d'affichage),

$(".temp_image").attr("src","str.jpg" ).load(function() { 
    // callback to get actual size of received image 

    // define to expand image in Height 
    if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
        $(".image").css('height', max_height_of_box);
        $(".image").css('width',' auto');
    } else { 
        // define to expand image in Width
        $(".image").css('width' ,max_width_of_box);
        $(".image").css('height','auto');
    }
    //Finally put the image to Completely Fill the display area while maintaining aspect ratio.
    $(".image").attr("src","str.jpg");
});

Cette approche est utile lorsque les images reçues sont plus petites que la zone d'affichage. Vous devez les enregistrer sur votre serveur en taille originale petite plutôt que dans leur version étendue pour remplir votre boîte d'affichage plus grande afin d'économiser sur la taille et la bande passante.

Yselection Rajeev Shukla
la source
Bien que le message de la question ne l'ait pas précisé, je pense que OP impliquait fortement qu'il / elle cherchait une solution CSS uniquement.
Flimm
0

img {
  max-width: 80px; /* Also works with percentage value like 100% */
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">

<p>Let's say the author of the HTML deliberately wants
  the height to be half the value of the width,
  this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">

Flimm
la source
0

Que diriez-vous d'utiliser un pseudo-élément pour l'alignement vertical? Ce moins de code est pour un carrousel mais je suppose que cela fonctionne sur tous les conteneurs de taille fixe. Il conservera le rapport hauteur / largeur et insérera @ barres gris-foncé en haut / en bas ou à gauche / écrire pour la dimension la plus courte. En attendant, l'image est centrée horizontalement par l'alignement du texte et verticalement par le pseudo-élément.

    > li {
      float: left;
      overflow: hidden;
      background-color: @gray-dark;
      text-align: center;

      > a img,
      > img {
        display: inline-block;
        max-height: 100%;
        max-width: 100%;
        width: auto;
        height: auto;
        margin: auto;
        text-align: center;
      }

      // Add pseudo element for vertical alignment of inline (img)
      &:before {
        content: "";
        height: 100%;
        display: inline-block;
        vertical-align: middle;
      }
    }
Paul Bormans
la source
0

Présentation plein écran:

img[data-attribute] {height: 100vh;}

Gardez à l'esprit que si la hauteur du port de vue est supérieure à l'image, l'image se dégradera naturellement par rapport à la différence.

John
la source
-1

Je pense, enfin que c'est la meilleure solution, simple et simple :

img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
}
Tu sais
la source
1
Pourriez-vous expliquer brièvement pourquoi cette solution est utile? (Une seule phrase suffit.)
Aenadon
Tout simplement parce que l'image gardera son rapport hauteur / largeur, tandis que la largeur et la hauteur maximales l'empêcheront de devenir plus grande que le conteneur
Uknow