web-dev-qa-db-fra.com

Existe-t-il un équivalent de background-size: cover et contient pour les éléments d’image?

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

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

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

Normalement j'utilise:

div.mydiv img {
    width: 100%;
}

Ou:

div.mydiv img {
    width: auto;
}

pour rendre la photo pleine et sensible. Cependant, l'image se réduit trop (width: 100%) lorsque l'écran devient trop étroit et affiche la couleur d'arrière-plan du corps dans l'écran du bas. L'autre méthode, width: auto;, agrandit uniquement l'image et ne répond pas à la taille de l'écran.

Est-il possible d'afficher l'image de la même manière que background-size: cover?

167
stormpat

Solution n ° 1 - La propriété object-fit ( manque de prise en charge IE )

Il suffit de définir 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 - en ce qui concerne object-fit: cover:

Le contenu remplacé est dimensionné pour conserver ses proportions tout en remplir toute la zone de contenu de l’élément. Si les proportions de l'objet ne correspond pas au rapport d'aspect de sa boîte, alors l'objet sera coupé pour s'adapter.

Voir aussi cette démonstration de Codepen qui compare object-fit: cover appliqué à une image avec background-size: cover appliqué à une image d'arrière-plan 


Solution n ° 2 - Remplacez l'image par une image d'arrière-plan par 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" />

288
Danield

Il existe en fait une solution simple css 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>

27
Simon

En supposant que vous puissiez organiser un élément de conteneur que vous souhaitez remplir, cela semble fonctionner, mais vous semble un peu rusé. En substance, j'utilise simplement min/max-width/height sur une zone plus grande, puis redimensionne cette zone aux 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>

14
Ulrich Schwarz

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

Cette approche est très proche: elle utilise JavaScript pour déterminer si l'image est au format paysage ou portrait et applique les 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/

8
roo2

J'avais besoin d'émuler background-size: contain, mais je ne pouvais pas utiliser object-fit en raison du manque de support. Mes images avaient des conteneurs avec des dimensions définies et cela a finalement fonctionné 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>

2
Gus

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

Notez que si vous n'avez pas besoin de supporter IE ou Edge avant 16 ans, vous feriez mieux d'utiliser object-fit.

taille du fond: 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>

La valeur de 1000% est utilisée ici si la taille naturelle de l'image est supérieure à la taille d'affichage. Par exemple, si l'image est 500x500, alors que le conteneur ne contient que 200x200. Avec cette solution, l'image sera redimensionnée à 2000x2000 (en raison de min-width/min-height), puis réduite à 200x200 (en raison de transform: scale(0.1)).

Le facteur x10 peut être remplacé par x100 ou x1000, mais il est généralement déconseillé de restituer une image 2000x2000 sur une image div en 20x20. :)

taille du fond: contient

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>

2
Thiago Barcala

Ce que vous pouvez faire est d'utiliser l'attribut 'style' pour ajouter l'image d'arrière-plan à l'élément. Ainsi, vous appellerez toujours l'image au format HTML, mais vous pourrez toujours utiliser le comportement background-size: cover css:

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 dans HTML. Vous pouvez ensuite utiliser des classes CSS impressionnantes comme background-position: center. boom

2
Charlie Tupman

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

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

( violon )

Si l'élément contenant votre image est position:relative ou 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 (set margin-left:-50%) ou verticalement (set margin-top:-50%). Il est peut-être possible d’utiliser des requêtes de médias CSS (et certaines mathématiques) pour comprendre cela.

2
Jeremy

Je sais que c'est vieux, mais beaucoup de solutions que je vois ci-dessus ont un problème avec l'image/vidéo étant trop volumineuses pour le conteneur, donc n'agissons pas comme une couverture de la taille de l'arrière-plan. Cependant, j'ai décidé de créer des "classes utilitaires" pour que cela fonctionne avec les images et les vidéos. Vous donnez simplement au conteneur la classe .media-cover-wrapper et le mé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

Lorsque vous l'appelez, veillez à prendre soin du redimensionnement de la page:

mediaCoverBounds();

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

Puis 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, jQuery peut être nécessaire, mais il répond assez bien et fonctionne exactement comme background-size: cover et vous pouvez l’utiliser sur des images et/ou des vidéos pour obtenir cette valeur de référencement supplémentaire.

0
Secular12

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

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

Avec CSS, vous pouvez simuler object-fit: [cover|contain];. C'est utiliser transform et [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>

0
mems

je ne suis pas autorisé à "ajouter un commentaire", ce qui fait que, ce que Eru Penkman a fait est assez bien sur place, pour que cela devienne une couverture d'arrière-plan, il suffit 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%;
}

0
Asim Ramay