Taille d'image CSS, comment remplir, pas étirer?

415

J'ai une image et je veux lui donner une largeur et une hauteur spécifiques (en pixels)

Mais si je règle la largeur et la hauteur à l'aide de css ( width:150px; height:100px), l'image sera étirée et elle peut être moche.

Comment remplir des images à une taille spécifique en utilisant CSS, sans l'étirer ?

Exemple d'image de remplissage et d'étirement:

Image originale:

Original

Image étirée:

Étiré

Image remplie:

Rempli

Veuillez noter que dans l'exemple d'image remplie ci-dessus: d'abord, l'image est redimensionnée à 150x255 (rapport d'aspect maintenu), puis elle est rognée à 150x100.

Mahdi Ghiasi
la source
Essayez simplement de régler le widthet heightdevrait ajuster en conséquence
NewInTheBusiness
3
Il étire l'image. voir ceci: jsfiddle.net/D7E3E
Mahdi Ghiasi
Il faut une partie de l'image non redimensionnée!
Ali Ben Messaoud
3
Chris Coyier a également de bonnes solutions à cela: css-tricks.com/perfect-full-page-background-image
ambiguousmouse
1
TRÈS IMPORTANT: c'est une pratique incroyablement mauvaise à des fins de référencement. Si vous l'utilisez comme image d'arrière-plan, cela fonctionne, mais si vous souhaitez que l'image soit trouvée par Google, elle ne sera PAS indexée s'il ne s'agit que d'une image d'arrière-plan.
Alex Banman

Réponses:

395

Si vous souhaitez utiliser l'image comme arrière-plan CSS, il existe une solution élégante. Utilisez simplement coverou containdans la background-sizepropriété CSS3.

.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%;
}
<div class="container"></div>

Tandis que cover vous donnera une image agrandie, containvous donnera une image réduite. Les deux conserveront le rapport hauteur / largeur des pixels.

http://jsfiddle.net/uTHqs/ (en utilisant la couverture)

http://jsfiddle.net/HZ2FT/ (en utilisant contain)

Cette approche a l'avantage d'être conviviale avec les écrans Retina selon le guide rapide de Thomas Fuchs.

Il convient de mentionner que la prise en charge du navigateur pour les deux attributs exclut IE6-8.

Marcelo De Polli
la source
1
Étant donné que vous pouvez redimensionner l'image uniquement dans le CSS, cela vous permet d'utiliser une grande image, puis de la réduire en fonction de la densité de pixels de chaque appareil à l'aide de requêtes multimédias.
Marcelo De Polli
1
Pourriez-vous expliquer pourquoi dans ce cas la position d'arrière-plan semble indiquer la position du centre de l'image plutôt que son coin supérieur gauche? Est-ce une conséquence de l'arrière-plan: la couverture?
matteo
1
le mien ne couvre que la DIV entière en élargissant l'image. Je ne vois pas la fin de la courbe.
SearchForKnowledge
3
À quoi ça sert background-repeat: no-repeat;? Si l'image recouvre son conteneur, elle ne se répétera pas de toute façon.
lurkit
3
'background-position' peut également être réglé sur 'center center'. par exemple: .container {... background-position: center center; }
Leo Ribeiro
556

Vous pouvez utiliser la propriété css object-fit.

.cover {
  object-fit: cover;
  width: 50px;
  height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Voir l'exemple ici

Il existe un polyfill pour IE: https://github.com/anselmh/object-fit

afonsoduarte
la source
11
Il est intéressant de voir que cela peut aussi être fait avec des imgbalises (pas seulement la background-imageméthode décrite dans la réponse ci-dessus). Merci :)
Mahdi Ghiasi
44
Lorsque vous envisagez cela comme une option, gardez à l'esprit que cela object-fit n'est pas pris en charge dans de nombreux navigateurs .
joshreesjones
2
Malheureusement, background-sizec'est rarement une solution viable dans mes projets. Vous êtes moins susceptible de bénéficier d'un avantage SEO et ne pouvez pas fournir une balise ALT, une légende, etc. pour accompagner l'image où vous pouvez fournir un contexte supplémentaire pour les lecteurs d'écran.
Markus
3
C'est cool, mais il n'y a pas de support IE. Aucun des polyfills ne fonctionne plus.
Jake
3
Il suffit de l'utiliser object-fit: cover;. Merci beaucoup
Luka
67

Amélioration de la réponse ci - dessus par @afonsoduarte ( PAS celle acceptée) .
au cas où vous utilisez bootstrap


Il y a trois différences:

  1. Fournir width:100%sur le style.
    Cela est utile si vous utilisez le bootstrap et souhaitez que l'image s'étire sur toute la largeur disponible.

  2. La spécification de la heightpropriété est facultative, vous pouvez la supprimer / la conserver selon vos besoins

    .cover {
       object-fit: cover;
       width: 100%;
       /*height: 300px;  optional, you can remove it, but in my case it was good */
    }
  3. Soit dit en passant, il n'est PAS nécessaire de fournir les attributs heightet widthsur l' imageélément car ils seront remplacés par le style.
    il suffit donc d'écrire quelque chose comme ça.

    <img class="cover" src="url to img ..."  />
Hakan Fıstık
la source
1
Exactement ce que je cherchais.
francis lanthier
1
Tu as besoin d'un baiser!
Qin Wang
l'ajustement d'objet ne fonctionne pas avec IE?
bgcode
1
nous sommes en 2020, je pense que c'est le bon moment pour abandonner IE
Hakan Fıstık
56

La seule vraie façon est d'avoir un conteneur autour de votre image et d'utiliser overflow:hidden:

HTML

<div class="container"><img src="ckk.jpg" /></div>

CSS

.container {
    width: 300px;
    height: 200px;
    display: block;
    position: relative;
    overflow: hidden;
}

.container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

C'est pénible en CSS de faire ce que l'on veut et de centrer l'image, il y a une solution rapide dans jquery comme:

var conHeight = $(".container").height();
var imgHeight = $(".container img").height();
var gap = (imgHeight - conHeight) / 2;
$(".container img").css("margin-top", -gap);

http://jsfiddle.net/x86Q7/2/

Dominic Green
la source
1
Merci. cela a fonctionné, mais il recadre l'image du haut . (voir ceci: jsfiddle.net/x86Q7 ) N'y a-t-il pas moyen de recadrer l'image du centre ?
Mahdi Ghiasi
1
@MahdiGhiasi: Modifiez les propriétés supérieure et gauche dans .container img css !!
Ali Ben Messaoud
Je peux définir l' margin-topimage par exemple 50px(voir ceci: jsfiddle.net/x86Q7/1 ), mais comment la recadrer à partir du centre réel ? (Sans jQuery?)
Mahdi Ghiasi
2
Ahh désolé n'a pas vu votre commentaire mais j'ai ajouté le jquery juste au cas où :)
Dominic Green
1
Excellente solution! Pour moi, le remplissage vertical était plus important que l'horizontale, j'ai donc juste eu à changer "largeur: 100%" en "hauteur: 100%" pour la classe '.container img'. Je vous remercie!
deebs
26

Solution CSS sans JS et sans image d'arrière-plan:

Méthode 1 "marge automatique" (IE8 + - PAS FF!):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  position:absolute; 
  top:0; 
  bottom:0; 
  margin: auto;
  width:100%;
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/

Méthode 2 "transformer" (IE9 +):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}

div img{
  position:absolute; 
  width:100%;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/1/

La méthode 2 peut être utilisée pour centrer une image dans un conteneur à largeur / hauteur fixe. Les deux peuvent déborder - et si l'image est plus petite que le conteneur, elle sera toujours centrée.

http://jsfiddle.net/5xjr05dt/3/

Méthode 3 "double wrapper" (IE8 + - PAS FF!):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    display: table;
    left: 50%;
}
.inner img {
    display: block;
    border: 1px solid blue; /* just for example */
    position: relative;
    right: 50%;
    opacity: .5; /* just for example */
}
<div class="outer">
  <div class="inner">
     <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/5/

Méthode 4 "double wrapper ET double image" (IE8 +):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 50%;
    bottom: 0;
    display: table;
    left: 50%;
}
.inner .real_image {
    display: block;
    border: 1px solid blue; /* just for example */
    position: absolute;
    bottom: 50%;
    right: 50%;
    opacity: .5; /* just for example */
}

.inner .placeholder_image{
  opacity: 0.1; /* should be 0 */
}
<div class="outer">
  <div class="inner">
    <img class="real_image" src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
    <img class="placeholder_image"  src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/26/

  • La méthode 1 offre un meilleur support - vous devez définir la largeur OU la hauteur de l'image!
  • Avec les préfixes, la méthode 2 a également un support décent (à partir de ie9) - La méthode 2 n'a pas de support sur Opera mini!
  • La méthode 3 utilise deux enveloppes - peut déborder de la largeur ET de la hauteur.
  • La méthode 4 utilise une double image (une comme espace réservé), ce qui donne une surcharge de bande passante supplémentaire, mais un meilleur support croisé.

Les méthodes 1 et 3 ne semblent pas fonctionner avec Firefox

JT Houtenbos
la source
C'est le seul qui fonctionne réellement (moins les solutions js). Merci!
Jake
Il se limite au débordement en hauteur ou en largeur, mais une solution intéressante.
Jake
1
@Jake - Il est possible de déborder la largeur ET la hauteur avec la méthode 2 ci-dessus - voir ma réponse mise à jour avec le violon supplémentaire.
JT Houtenbos
Ouais. C'est certainement une excellente réponse. Je vais encore jouer avec. C'était un peu excentrique pour une image plus large que plus grande qui devait être réactive, mais il existe de nombreuses applications pour cela.
Jake
1
@Jake - Cool - J'ai trouvé une 3ème méthode pour faire un centrage horizontal. J'ai étendu cette méthode pour prendre également en charge le centrage vertical. Je publierai mon ajout comme troisième méthode ci-dessus. Il semble que ce soit la preuve IE7 + (peut-être même plus bas). Voici la réponse originale: stackoverflow.com/questions/3300660/…
JT Houtenbos
10

Une autre solution consiste à mettre l'image dans un récipient de la largeur et de la hauteur souhaitées. En utilisant cette méthode, vous n'auriez pas à définir l'image comme image d'arrière-plan d'un élément.

Ensuite, vous pouvez le faire avec une imgbalise et définir simplement une largeur maximale et une hauteur maximale sur l'élément.

CSS:

.imgContainer {
    display: block;
    width: 150px; 
    height: 100px;
}

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

HTML:

<div class='imgContainer'>
    <img src='imagesrc.jpg' />
</div>

Désormais, lorsque vous modifiez la taille du conteneur, l'image s'agrandit automatiquement autant qu'elle peut sans sortir des limites ni se déformer.

Si vous souhaitez centrer l'image verticalement et horizontalement, vous pouvez changer le conteneur CSS pour:

.imgContainer {
    display: table-cell;
    width: 150px; 
    height: 100px;
    text-align: center;
    vertical-align: middle;
}

Voici un JS Fiddle http://jsfiddle.net/9kUYC/2/

earl3s
la source
Ce n'est pas la même chose que la couverture en CSS, où l'une des dimensions résultantes est toujours au-delà de 100% (ou égale dans le cas de bord)
Miroshko
Non, cette solution garantit qu'elle ne dépasse jamais 100%, ce qui était la partie de la question. Ils ne voulaient pas que l'image se déforme ou croisse au-delà des dimensions d'origine.
earl3s
3
La question était "Comment remplir" avec un exemple d'image remplie, qui est évidemment recadrée.
Miroshko
Mais que faire si vous avez besoin que l'image soit réactive? Définir une largeur et une hauteur spécifiques ne fonctionnera pas 😕
Ricardo Zea
2
C'était ce dont j'avais besoin. Merci!
Nico Rodsevich
5

À partir de la réponse de @Dominic Green à l'aide de jQuery, voici une solution qui devrait fonctionner pour des images qui sont soit plus larges que hautes, soit plus hautes qu'elles ne sont larges.

http://jsfiddle.net/grZLR/4/

Il existe probablement une façon plus élégante de faire le JavaScript, mais cela fonctionne.

function myTest() {
  var imgH = $("#my-img").height();
  var imgW = $("#my-img").width();
  if(imgW > imgH) {
    $(".container img").css("height", "100%");
    var conWidth = $(".container").width();
    var imgWidth = $(".container img").width();
    var gap = (imgWidth - conWidth)/2;
    $(".container img").css("margin-left", -gap);
  } else {
    $(".container img").css("width", "100%");
    var conHeight = $(".container").height();
    var imgHeight = $(".container img").height();
    var gap = (imgHeight - conHeight)/2;
    $(".container img").css("margin-top", -gap);
  }
}
myTest();
ramdog
la source
5
  • Ne pas utiliser le fond CSS
  • Seulement 1 div pour le couper
  • Redimensionné à la largeur minimale que garder le rapport d'aspect correct
  • Recadrer à partir du centre (verticalement et horizontalement, vous pouvez ajuster cela avec le haut, lef & transformer)

Soyez prudent si vous utilisez un thème ou quelque chose, ils déclarent souvent img max-width à 100%. Tu dois en faire aucun. Testez-le :)

https://jsfiddle.net/o63u8sh4/

<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
    <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>


div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  min-width:100%;
  min-height:100%;
  height:auto;
  position:relative;
  top:50%;
  left:50%;
  transform:translateY(-50%) translateX(-50%);
}
dmegatool
la source
C'est la réponse que je cherchais.
Marcos Buarque
C'est ce que je voulais faire depuis longtemps, merci;)
Boss COTIGA
4

J'ai aidé à construire un plugin jQuery appelé Fillmore , qui gère les background-size: covernavigateurs dans qui le prennent en charge, et a un shim pour ceux qui ne le font pas. Donnez-lui un coup d'oeil!

Aidan Feldman
la source
4

Je pense qu'il est assez tard pour cette réponse. Quoi qu'il en soit, j'espère que cela aidera quelqu'un à l'avenir. J'ai rencontré le problème de positionnement angulaire des cartes. Il y a des cartes affichées pour un éventail d'événements. Si la largeur de l'image de l'événement est grande pour la carte, l'image doit être affichée en recadrant des deux côtés et une hauteur de 100%. Si la hauteur de l'image est longue, la partie inférieure des images est rognée et la largeur est de 100%. Voici ma solution CSS pure pour cela:

entrez la description de l'image ici

HTML:

 <span class="block clear img-card b-b b-light text-center" [ngStyle]="{'background-image' : 'url('+event.image+')'}"></span>

CSS

.img-card {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
width: 100%;
overflow: hidden;
}
Nodirabegimxonoyim
la source
je ne peux pas comprendre comment cela fonctionne, mais c'est le cas. Vous devez positionner la plage absolument en haut: 0; à droite: 0; en bas: 0; à gauche: 0 à l'intérieur du parent relativement positionné pour le coter.
Mike
Merci pour vos commentaires, cher Mike, je suis heureux si cela a été utile. Voulez-vous que je mette à jour la réponse avec votre commentaire?
Nodirabegimxonoyim
3

Essayez quelque chose comme ceci: http://jsfiddle.net/D7E3E/4/

Utilisation d'un conteneur avec débordement: caché

EDIT: @Dominic Green m'a battu.

woutr_be
la source
Merci. cela a fonctionné, mais il recadre l'image du haut . (voir ceci: jsfiddle.net/x86Q7 ) N'y a-t-il pas moyen de recadrer l'image du centre ?
Mahdi Ghiasi
Cela pourrait être assez difficile avec CSS, c'est le meilleur que j'ai pu trouver avec jsfiddle.net/D7E3E/5
woutr_be
Oui, pour le centrer correctement, vous devriez utiliser jQuery, cela pourrait être beaucoup plus facile.
woutr_be
3

Cela remplira les images à une taille spécifique, sans les étirer ni les recadrer

img{
    width:150px;  //your requirement size
    height:100px; //your requirement size

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

Pour adapter l'image en plein écran, essayez ceci:

fond-répétition: rond;

suyash1798
la source
0
<div class="container">
     <img src="http://i.stack.imgur.com/2OrtT.jpg"/>
</div>

<style>
.container {
       width: 150px;
       height: 100px;
       overflow: hidden;
}
</style>
user3181614
la source