Existe-t-il un équivalent à background-size: couvrir et contenir pour les éléments d'image?

241

J'ai un site avec de nombreuses pages et différentes images de fond, et je les affiche depuis CSS comme:

body.page-8 {
    background: url("../img/pic.jpg") no-repeat scroll center top #000;
    background-size: cover;
}

Cependant, je veux montrer différentes images (plein écran) sur une page en utilisant des <img>éléments, et je veux qu'elles aient les mêmes propriétés que la background-image: cover;propriété ci-dessus (les images ne peuvent pas être affichées à partir de CSS, elles doivent être affichées à partir du document HTML).

J'utilise normalement:

div.mydiv img {
    width: 100%;
}

Ou:

div.mydiv img {
    width: auto;
}

pour rendre l'image complète et réactive. Cependant, l'image rétrécit trop ( width: 100%) lorsque l'écran devient trop étroit et affiche la couleur d'arrière-plan du corps dans l'écran inférieur. L'autre méthode,width: auto; ne fait que rendre l'image pleine taille et ne répond pas à la taille de l'écran.

Existe-t-il un moyen d'afficher l'image de la même manière background-size: cover?

Stormpat
la source
Grande question.
wonsuc

Réponses:

380

Solution # 1 - La propriété d'ajustement d'objet ( manque de support IE )

Mettez juste object-fit: cover;sur l'img.

body {
  margin: 0;
}
img {
  display: block;
  width: 100vw;
  height: 100vh;
  object-fit: cover;
}
<img src="http://lorempixel.com/1500/1000" />

Voir MDN - concernant object-fit: cover:

Le contenu remplacé est dimensionné pour conserver son rapport hauteur / largeur tout en remplissant la zone de contenu entière de l'élément. Si le rapport hauteur / largeur de l'objet ne correspond pas au rapport hauteur / largeur de sa boîte, l'objet sera découpé pour s'adapter.

Voir aussi cette démo Codepen qui compare object-fit: coverappliqué à une image avec background-size: coverappliqué à une image d'arrière-plan


Solution # 2 - Remplacez l'img par une image d'arrière-plan avec CSS

body {
  margin: 0;
}
img {
  position: fixed;
  width: 0;
  height: 0;
  padding: 50vh 50vw;
  background: url(http://lorempixel.com/1500/1000/city/Dummy-Text) no-repeat;
  background-size: cover;
}
<img src="http://placehold.it/1500x1000" />

Danield
la source
3
Au moment de ce commentaire, l'ajustement d'objet n'est pas encore pris en charge par aucune version d'Internet Explorer (même Edge). Elle est cependant à l'étude .
Mike Kormendy
3
l'ajustement d'objet n'est toujours pas pris en charge dans IE. Je resterais à l'écart si sur le site de production et que vous vous souciez des utilisateurs d'IE.
Travis Michael Heller
2
Vous pouvez également ajouter polyfill pour # 1 pour IE et l'ancien Safari: github.com/bfred-it/object-fit-images
Valera Tumash
1
Attention à la deuxième solution. Mieux vaut
sudokai
1
@RoCk, vous pouvez trouver des trucs comme ça sur caniuse: caniuse.com/#search=background-att :) PS Je pense que nous pouvons tous être assurés qu'IE n'obtiendra jamais de support pour cette fonctionnalité et puisqu'il n'y a pas non plus de polyfill, nous ' re foutu ou coincé avec des hacks JS / CSS jusqu'à ce que MS décide qu'il est temps (enfin) de "tuer" IE en le supprimant de Windows.
SidOfc
31

Il existe en fait une solution CSS assez simple qui fonctionne même sur IE8:

.container {
  position: relative;
  overflow: hidden;
  /* Width and height can be anything. */
  width: 50vw;
  height: 50vh;
}

img {
  position: absolute;
  /* Position the image in the middle of its container. */
  top: -9999px;
  right: -9999px;
  bottom: -9999px;
  left: -9999px;
  margin: auto;
  /* The following values determine the exact image behaviour. */
  /* You can simulate background-size: cover/contain/etc.
     by changing between min/max/standard width/height values.
     These values simulate background-size: cover
  */
  min-width: 100%;
  min-height: 100%;
}
<div class="container">
    <img src="http://placehold.it/200x200" alt="" />
</div>

Simon
la source
9
Cela ne reproduit pas le comportement de la couverture, mais recadre une section centrée à partir de l'img src. Voir jsfiddle.net/sjt71j99/4 - la première img est votre recadrage, la prochaine est via background-size: cover, c'est-à-dire ce que nous voulons, la troisième est l'img originale. J'ai trouvé que pour les images de paysage, remplacez min-height & min-width par max-height: 100%; pour une utilisation en portrait largeur max: 100%. Ce serait bien s'il y avait une solution qui fonctionnait pour le paysage ou le portrait. Des idées? C'est la meilleure solution multi-navigateur que j'ai vue jusqu'à présent.
terraling du
1
Vous avez raison, cela ne fait pas exactement la même chose, j'ai essayé quelques trucs mais il semble que vous ne puissiez pas le faire reproduire la couverture à 100%, cela fonctionne tant que l'image est plus petite que le conteneur sur une dimension bien que.
Simon
@terraling, je sais que c'est un vieux commentaire, mais vérifiez ma réponse . Il utilise la transformation pour positionner l'img au centre.
Thiago Barcala
30

En supposant que vous pouvez vous arranger pour avoir un élément de conteneur que vous souhaitez remplir, cela semble fonctionner, mais semble un peu hackish. Essentiellement, je l'utilise simplement min/max-width/heightsur une zone plus grande, puis redimensionne cette zone dans ses dimensions d'origine.

.container {
  width: 800px;
  height: 300px;
  border: 1px solid black;
  overflow:hidden;
  position:relative;
}
.container.contain img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  max-width: 10%;
  max-height: 10%;
  -webkit-transform:scale(10);
  transform: scale(10);
}
.container.cover img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  min-width: 1000%;
  min-height: 1000%;
  -webkit-transform:scale(0.1);
  transform: scale(0.1);
}
<h1>contain</h1>
  <div class="container contain">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>
  <h1>cover</h1>
  <div class="container cover">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>

Ulrich Schwarz
la source
1
Entièrement d'accord. Ceci est la meilleure solution de tous ci-dessus pour une utilisation générale.
Varis Vītols
C'est bien. Ça m'a aidé. Merci
Raman Nikitsenka
14

J'ai trouvé une solution simple pour émuler à la fois la couverture et le contenu, qui est purement CSS, et fonctionne pour les conteneurs avec des dimensions dynamiques, et ne fait aucune restriction sur le rapport d'image.

Notez que si vous n'avez pas besoin de prendre en charge IE ou Edge avant 16, vous feriez mieux d'utiliser l'ajustement d'objet.

taille de l'arrière-plan: couverture

.img-container {
  position: relative;
  overflow: hidden;
}

.background-image {
  position: absolute;
  min-width: 1000%;
  min-height: 1000%;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%) scale(0.1);
  z-index: -1;
}
<div class="img-container">
  <img class="background-image" src="https://picsum.photos/1024/768/?random">
  <p style="padding: 20px; color: white; text-shadow: 0 0 10px black">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>

Le 1000% est utilisé ici au cas où la taille naturelle de l'image est plus grande que la taille affichée. Par exemple, si l'image est 500x500, mais le conteneur est seulement 200x200. Avec cette solution, l'image sera redimensionnée à 2000x2000 (en raison de min-largeur / min-hauteur), puis réduite à 200x200 (en raison de transform: scale(0.1)).

Le facteur x10 peut être remplacé par x100 ou x1000, mais il n'est généralement pas idéal d'avoir une image 2000x2000 rendue sur un div 20x20. :)

taille de l'arrière-plan: contenir

En suivant le même principe, vous pouvez également l'utiliser pour émuler background-size: contain:

.img-container {
  position: relative;
  overflow: hidden;
  z-index: 0;
}

.background-image {
  position: absolute;
  max-width: 10%;
  max-height: 10%;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%) scale(10);
  z-index: -1;
}
<div style="background-color: black">
  <div class="img-container">
    <img class="background-image" src="https://picsum.photos/1024/768/?random">
    <p style="padding: 20px; color: white; text-shadow: 0 0 10px black">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>
</div>

Thiago Barcala
la source
L'astuce d'échelle est déjà donnée ici https://stackoverflow.com/a/28771894/2827823 , donc je ne vois pas l'intérêt d'en publier encore une autre, et c'est le cas transformdans de nombreuses réponses
Ason
Si vous souhaitez développer avec une explication, mettez à jour cette réponse à la place, car il n'y a pas besoin de 2 avec la même solution
Ason
1
Merci pour ton commentaire @LGSon. Je n'avais pas vu cette réponse auparavant, mais je pense toujours que ma réponse a sa valeur ici. L'approche est à peu près la même, mais à mon avis, la mienne est présentée d'une manière légèrement plus propre. De nombreuses autres réponses ici présentent la même solution, et toutes sont incomplètes (à l'exception de celle que vous avez liée). Donc, si ma réponse ne devrait pas être ici, les autres non plus.
Thiago Barcala
1
Je l'ai trouvé rétrécir l'image dans le navigateur mobile Chrome sur Android (testé sur LG G3 et Samsung S9), je ne l'ai pas testé avec Chrome sur iOS, Firefox mobile sur Android l'a affiché correctement.
Jecko
10

Non , vous ne pouvez pas l'obtenir comme background-size:cover mais ...

Cette approche est sacrément proche: elle utilise JavaScript pour déterminer si l'image est en paysage ou en portrait, et applique des styles en conséquence.

JS

 $('.myImages img').load(function(){
        var height = $(this).height();
        var width = $(this).width();
        console.log('widthandheight:',width,height);
        if(width>height){
            $(this).addClass('wide-img');
        }else{
            $(this).addClass('tall-img');
        }
    });

CSS

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

http://jsfiddle.net/b3PbT/

roo2
la source
3

J'avais besoin d'émuler background-size: contain, mais je n'ai pas pu l'utiliser en object-fitraison du manque de support. Mes images avaient des conteneurs avec des dimensions définies et cela a fini par fonctionner pour moi:

.image-container {
  height: 200px;
  width: 200px;
  overflow: hidden;
  background-color: rebeccapurple;
  border: 1px solid yellow;
  position: relative;
}

.image {
  max-height: 100%;
  max-width: 100%;
  margin: auto;
  position: absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
}
<!-- wide -->
<div class="image-container">
  <img class="image" src="http://placehold.it/300x100">
</div>

<!-- tall -->
<div class="image-container">
  <img class="image" src="http://placehold.it/100x300">
</div>

Gus
la source
Vous pouvez utiliser min-height: 100%; max-height:100%;et obtenir l'équivalent de la taille d'arrière-plan: couverture;
Chris Seufert
min-height: 100%; max-height:100%;ne conserverait pas les proportions, donc pas exactement un équivalent.
Reedyn
2

Essayez de régler les deux min-height et min-width, avec display:block:

img {
    display:block;
    min-height:100%;
    min-width:100%;
}

( violon )

À condition que l'élément contenant votre image soit position:relativeou position:absolute, l'image couvrira le conteneur. Cependant, il ne sera pas centré.

Vous pouvez facilement centrer l'image si vous savez si elle débordera horizontalement (définir margin-left:-50% ) ou verticalement (ensemble margin-top:-50%). Il peut être possible d'utiliser des requêtes de médias CSS (et quelques mathématiques) pour comprendre cela.

Jeremy
la source
2

Avec CSS, vous pouvez simuler object-fit: [cover|contain];. C'est utiliser transformet [max|min]-[width|height]. Ce n'est pas parfait. Cela ne fonctionne pas dans un cas: si l'image est plus large et plus courte que le conteneur.

.img-ctr{
  background: red;/*visible only in contain mode*/
  border: 1px solid black;
  height: 300px;
  width: 600px;
  overflow: hidden;
  position: relative;
  display: block;
}
.img{
  display: block;

  /*contain:*/
  /*max-height: 100%;
  max-width: 100%;*/
  /*--*/

  /*cover (not work for images wider and shorter than the container):*/
  min-height: 100%;
  width: 100%;
  /*--*/

  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<p>Large square:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x1000"></span>
</p>
<p>Small square:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x100"></span>
</p>
<p>Large landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/2000x1000"></span>
</p>
<p>Small landscape:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x100"></span>
</p>
<p>Large portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x2000"></span>
</p>
<p>Small portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/100x200"></span>
</p>
<p>Ultra thin portrait:
<span class="img-ctr"><img class="img" src="http://placehold.it/200x1000"></span>
</p>
<p>Ultra wide landscape (images wider and shorter than the container):
<span class="img-ctr"><img class="img" src="http://placehold.it/1000x200"></span>
</p>

mems
la source
2

Ce que vous pourriez faire, c'est utiliser l'attribut 'style' pour ajouter l'image d'arrière-plan à l'élément, de cette façon, vous appellerez toujours l'image dans le code HTML, mais vous pourrez toujours utiliser le comportement CSS de background-size: cover:

HTML:

    <div class="image-div" style="background-image:url(yourimage.jpg)">
    </div>

CSS:

    .image-div{
    background-size: cover;
    }

Voici comment j'ajoute le comportement background-size: cover aux éléments que je dois charger dynamiquement en HTML. Vous pouvez ensuite utiliser des classes CSS impressionnantes comme background-position: center. boom

Charlie Tupman
la source
1
Principalement la séparation des préoccupations, mais en voici quelques autres: programmers.stackexchange.com/a/271338
Daan
0

Pour IE, vous devez également inclure la deuxième ligne - largeur: 100%;

.mydiv img {
    max-width: 100%;
    width: 100%;
}
фымышонок
la source
0

je ne suis pas autorisé à `` ajouter un commentaire '' en faisant cela, mais oui, ce qu'a fait Eru Penkman est à peu près sur place, pour obtenir une couverture de fond, tout ce que vous devez faire est de changer

.tall-img{
    margin-top:-50%;
    width:100%;
}
.wide-img{
    margin-left:-50%;
    height:100%;
}

À

.wide-img{
    margin-left:-42%;
    height:100%;
}
.tall-img{
    margin-top:-42%;
    width:100%;
}

Asim Ramay
la source
0

Je sais que c'est ancien, mais de nombreuses solutions que je vois ci-dessus ont un problème avec l'image / vidéo étant trop grande pour le conteneur, donc n'agissant pas réellement comme une couverture de taille d'arrière-plan. Cependant, j'ai décidé de créer des "classes utilitaires" afin que cela fonctionne pour les images et les vidéos. Vous donnez simplement au conteneur la classe .media-cover-wrapper et l'élément multimédia lui-même la classe .media-cover

Ensuite, vous avez le jQuery suivant:

function adjustDimensions(item, minW, minH, maxW, maxH) {
  item.css({
  minWidth: minW,
  minHeight: minH,
  maxWidth: maxW,
  maxHeight: maxH
  });
} // end function adjustDimensions

function mediaCoverBounds() {
  var mediaCover = $('.media-cover');

  mediaCover.each(function() {
   adjustDimensions($(this), '', '', '', '');
   var mediaWrapper = $(this).parent();
   var mediaWrapperWidth = mediaWrapper.width();
   var mediaWrapperHeight = mediaWrapper.height();
   var mediaCoverWidth = $(this).width();
   var mediaCoverHeight = $(this).height();
   var maxCoverWidth;
   var maxCoverHeight;

   if (mediaCoverWidth > mediaWrapperWidth && mediaCoverHeight > mediaWrapperHeight) {

     if (mediaWrapperHeight/mediaWrapperWidth > mediaCoverHeight/mediaCoverWidth) {
       maxCoverWidth = '';
       maxCoverHeight = '100%';
     } else {
       maxCoverWidth = '100%';
       maxCoverHeight = '';
     } // end if

     adjustDimensions($(this), '', '', maxCoverWidth, maxCoverHeight);
   } else {
     adjustDimensions($(this), '100%', '100%', '', '');
   } // end if
 }); // end mediaCover.each
} // end function mediaCoverBounds

Lors de l'appel, assurez-vous de prendre soin du redimensionnement de la page:

mediaCoverBounds();

$(window).on('resize', function(){
  mediaCoverBounds();
});

Ensuite, le CSS suivant:

.media-cover-wrapper {
  position: relative;
  overflow: hidden;
}

.media-cover-wrapper .media-cover {
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  -ms-transform: translate(-50%, -50%);
  -moz-transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

Oui, cela peut nécessiter jQuery mais il répond assez bien et agit exactement comme la taille de l'arrière-plan: couverture et vous pouvez l'utiliser sur des images et / ou des vidéos pour obtenir cette valeur SEO supplémentaire.

Laïque12
la source
0

Nous pouvons adopter l'approche ZOOM. Nous pouvons supposer que max 30% (ou plus jusqu'à 100%) peut être l'effet de zoom si la hauteur ou la largeur de l'image d'aspect est inférieure à la hauteur OU largeur souhaitée. Nous pouvons masquer le reste de la zone non nécessaire avec débordement: caché.

.image-container {
  width: 200px;
  height: 150px;
  overflow: hidden;
}
.stage-image-gallery a img {
  max-height: 130%;
  max-width: 130%;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}

Cela ajustera les images avec une largeur OU une hauteur différente.

Rehmat
la source
-1
background:url('/image/url/') right top scroll; 
background-size: auto 100%; 
min-height:100%;

rencontré les mêmes symptômes exacts. ci-dessus a fonctionné pour moi.

user2958520
la source