Comment définir la largeur et la hauteur d'une image sans l'étirer?

87

Si j'ai:

#logo {
    width: 400px;
    height: 200px;
}

puis

<img id="logo" src="logo.jpg"/>

s'étendra pour remplir cet espace. Je veux que l'image garde la même taille, mais qu'elle prenne autant de place dans le DOM. Dois-je ajouter un encapsulant <div>ou <span>? Je déteste ajouter du balisage pour le style.

Paul Tarjan
la source
Si vous êtes toujours sur Stack Overflow, souhaitez-vous envisager de mettre à jour la réponse?
mikemaccana

Réponses:

116

Oui, vous avez besoin d'un div encapsulant:

<div id="logo"><img src="logo.jpg"></div>

avec quelque chose comme:

#logo { height: 100px; width: 200px; overflow: hidden; }

D'autres solutions (remplissage, marge) sont plus fastidieuses (dans la mesure où vous devez calculer la bonne valeur en fonction des dimensions de l'image) mais ne permettent pas non plus efficacement que le conteneur soit plus petit que l'image.

En outre, ce qui précède peut être adapté beaucoup plus facilement pour différentes dispositions. Par exemple, si vous voulez l'image en bas à droite:

#logo { position: relative; height: 100px; width: 200px; }
#logo img { position: absolute; right: 0; bottom: 0; }
cletus
la source
5
Vous pouvez remplacer la balise <div> par <figure>: ajoute de la sémantique et vous pouvez lui donner une légende (<figcaption>), si nécessaire. developer.mozilla.org/en-US/docs/Web/HTML/Element/figure
Mateus Leon
De plus, s'il s'agit d'une utilisation de marque, sur la présentation du site Web, utilisez <h1> (si index) ou <p> (si autre), en appliquant les attributs title et alt au <img>, afin que vous puissiez ajouter un balisage convivial pour le référencement. . Ce sont également des éléments de niveau bloc, comme div, et peuvent être des wrappers pour votre fonctionnalité de recadrage.
Mateus Leon
3
Je n'avais aucune idée que Cletus était un développeur Web. Amazing
Piyin
61

Réponse 2017

L'ajustement d'objet CSS fonctionne dans tous les navigateurs actuels. Cela permet à l' imgélément d'être plus grand sans étirer l'image.

Vous pouvez ajouter object-fit: cover;à votre CSS.

Dante
la source
2
Vous devriez probablement mentionner sur quels navigateurs il fonctionne.
Nathan Tuggy
2
vérifiez ce lien pour la compatibilité du navigateur: caniuse.com/#search=object-fit
Alexee
28

Chargez l'image comme arrière-plan d'un div.

Au lieu de:

<img id='logo' src='picture.jpg'>

faire

<div id='logo' style='background:url(picture.jpg)'></div>

Tous les navigateurs recadreront la partie de l'image qui ne rentre pas.
Cela présente plusieurs avantages par rapport à l'envelopper d'un élément dont le débordement est masqué:

  1. Pas de majoration supplémentaire. Le div remplace simplement l'img.
  2. Centrez facilement ou réglez l'image sur un autre décalage. par exemple.url(pic) center top;
  3. Répétez l'image lorsqu'elle est assez petite. (OK, je ne sais pas pourquoi tu voudrais ça)
  4. Définissez une couleur bg dans la même instruction, appliquez facilement la même image à plusieurs éléments et tout ce qui s'applique aux images bg.

Mise à jour: Cette réponse est d'avant ajustement d'objet; vous devriez maintenant probablement utiliser object-fit / object-position.

Il est toujours utile pour les navigateurs plus anciens, pour des propriétés supplémentaires (telles que la répétition d'arrière-plan) et pour les cas extrêmes (par exemple, pour contourner les bogues Chrome avec flexbox et position d'objet et les problèmes de FF (ancien?) Avec grille + hauteur automatique + objet- Les divs de wrapper dans grid / flexbox donnent souvent ... des résultats peu intuitifs.)

SamGoody
la source
4
Ceux qui ont donné un -1 doivent expliquer pour le bénéfice des autres utilisateurs. Personnellement, je l'ai fait avec d'excellents résultats, même sur IE6 et Safari sur iOS.
SamGoody
Je voulais juste ajouter - c'est généralement une bonne approche. Les gens spécifient même les coordonnées de position d'arrière-plan pour les feuilles de sprite d'image comme optimisation. Une différence, cependant, est qu'il n'a pas le gestionnaire d'événements d'erreur que <img> a
badunk
J'ai également ajouté une classe à la div avec ce contenu:background-repeat:no-repeat !important; float:left; width:100px; height:100px;
Nils
2
Certains navigateurs n'impriment pas par défaut les images d'arrière-plan, ce n'est donc peut-être pas une bonne approche si vous souhaitez permettre aux utilisateurs d'imprimer cette page.
Bennett McElwee
5
Ce n'est pas sémantiquement correct. Si cela est utile, pourquoi le HTML5 place plus de balises liées à l'image, pour optimiser la sémantique, avec figcaption, picture? Utilisez la balise img telle qu'elle a été conçue et arrêtez de tout remplacer par des <div>.
Mateus Leon
23

Ajustement d'objet CSS3

Je ne sais pas dans quelle mesure il a été mis en œuvre par webkit, IE et Firefox. Mais Opera fonctionne comme par magie

object-fitfonctionne avec le contenu SVG, mais le même effet peut également être obtenu en définissant l' preserveAspectRatio=""attribut dans le SVG lui-même.

img {
  height: 100px;
  width: 100px;
  -o-object-fit: contain;
}

La démo de Chris Mills est ici http://dev.opera.com/articles/view/css3-object-fit-object-position/

le crabe
la source
2
1+ C'est vraiment cool. Dommage que le support soit limité. Il semble que Chrome 32 soit le premier à le prendre en charge sans préfixes de fournisseurs.
Josh Crozier
C'est fantastique, ça marche comme un charme. L'ajout d'une seule propriété a tout résolu. J'avais juste besoin de Chrome et ça marche. Et oui, sans préfixe de fournisseur. Merci.
whyAto8
9
#logo {
    width: 400px;
    height: 200px;

    /*Scale down will take the necessary specified space that is 400px x 200px without stretching the image*/
    object-fit:scale-down;
}
Manoj Selvin
la source
7

Faites un div et donnez-lui une classe. Puis déposez-y une image.

<div class="mydiv">

<img src="location/of/your/image" ></img>

</div>

Définissez la taille de votre div et rendez-la relative.

    .mydiv {
        position: relative;
        height:300px;
        width: 100%;
        overflow: hidden;
    }

puis stylisez votre image

img {
    width: 100%;
    height: auto;
    overflow: hidden;
}

J'espère que ça t'as aidé

Sabba Keynejad
la source
2

Vous pouvez utiliser comme ci-dessous:

.width100 {
  max-width: 100px;
  height: 100px;
  width: auto;
  border: solid red;
}
<img src="https://www.gravatar.com/avatar/dc48e9b92e4210d7a3131b3ef46eb8b1?s=512&d=identicon&r=PG" class="width100" />

PurTahan
la source
1

Dois-je ajouter un <div> ou un <span> encapsulant?

Je pense que oui. La seule chose qui vous vient à l'esprit est le rembourrage, mais pour cela, vous devez connaître les dimensions de l'image au préalable.

Pekka
la source
0

vous pouvez essayer de définir le remplissage au lieu de la hauteur / largeur.

Bénissez Yahu
la source
0

Ce à quoi je peux penser, c'est d'étirer la largeur ou la hauteur et de le laisser se redimensionner en rapport-aspect. Il y aura un espace blanc sur les côtés. Quelque chose comme la façon dont un écran large affiche une résolution de 1024x768.

Mauris
la source
0

Si l'utilisation de flexbox est une option valable pour vous (vous n'avez pas besoin de prendre en charge d'anciens navigateurs), vérifiez mon autre réponse ici (qui est peut-être un double de celle-ci):

En gros, vous devez envelopper votre balise img dans un div et votre css ressemblerait à ceci:

.img__container {
    display: flex;
    padding: 15px 12px;
    box-sizing: border-box;
    width: 400px; height: 200px;

    img {
        margin: auto;
        max-width: 100%;
        max-height: 100%;
    }
}
rafaelbiten
la source
-1

C'est une question assez ancienne, mais j'ai eu exactement le même problème ennuyeux où tout fonctionnait bien pour Chrome / Edge (avec la propriété object-fit) mais la même propriété css ne fonctionnait pas dans IE11 (car elle n'est pas prise en charge dans IE11), j'ai fini par en utilisant l'élément "figure" HTML5 qui a résolu tous mes problèmes.

Personnellement, je n'ai pas utilisé la balise DIV externe car cela n'a pas du tout aidé dans mon cas, j'ai donc évité le DIV externe et simplement remplacé par l'élément «figure».

Le code ci-dessous force l'image à réduire / réduire bien (sans changer le rapport hauteur / largeur d'origine).

<figure class="figure-class">
  <img class="image-class" src="{{photoURL}}" />
</figure>

et classes css:

.image-class {
    border: 6px solid #E8E8E8;
    max-width: 189px;
    max-height: 189px;
}

.figure-class {
    width: 189px;
    height: 189px;
}
nakul2013
la source