¿Hay un equivalente a background-size: cover y contain para los elementos de imagen?


Tengo un sitio con muchas páginas y diferentes imágenes de fondo, y las muestro desde CSS como:

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

Sin embargo, quiero mostrar diferentes imágenes (a pantalla completa) en una página usando elementos <img>, y quiero que tengan las mismas propiedades que la propiedad background-image: cover; anterior (las imágenes no se pueden mostrar desde CSS, deben mostrarse desde el documento HTML).

Normalmente uso:

div.mydiv img {
    width: 100%;
}

O:

div.mydiv img {
    width: auto;
}

Para hacer la imagen completa y sensible. Sin embargo, el la imagen se encoge demasiado (width: 100%) cuando la pantalla se estrecha demasiado, y muestra el color de fondo del cuerpo en la pantalla inferior. El otro método, width: auto;, solo hace que la imagen sea de tamaño completo y no responde al tamaño de la pantalla.

¿Hay alguna forma de mostrar la imagen de la misma manera que background-size: cover?

Author: Michael, 2012-07-26

14 answers

Solución # 1-La nueva propiedad object-fit de (No hay soporte de IE todavía )

Simplemente establece object-fit: cover; en el img .

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

Puede leer más sobre esta nueva propiedad en este artículo de la plataforma web .

Del artículo anterior-con respecto al valor de 'cubierta':

Toda la imagen se reduce o se expande hasta que llena la caja completamente, la relación de aspecto se mantiene. Esto normalmente resulta en solo parte de la imagen siendo visible.

También, aquí está un violín del artículo anterior que demuestra todos los valores de la propiedad object-fit.

Solución # 2-Reemplazar el img con una imagen de fondo con 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" />
 251
Author: Danield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-27 09:49:56

En realidad hay una solución css bastante simple que incluso funciona en 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>
 22
Author: Simon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-11 10:54:05

Suponiendo que se puede arreglar para tener un elemento contenedor que desea llenar, esto parece funcionar, pero se siente un poco hackish. En esencia, solo uso min/max-width/height en un área más grande y luego escalo esa área de nuevo a las dimensiones originales.

.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>
 11
Author: Ulrich Schwarz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-27 18:30:20

No, no se puede conseguir bastante como background-size:cover pero..

Este enfoque está bastante cerca: utiliza JavaScript para determinar si la imagen es horizontal o vertical, y aplica estilos en consecuencia.

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
Author: roo2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-17 16:57:15

Intenta configurar ambos min-height y min-width, con display:block:

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

(fiddle )

Siempre que el elemento que contiene la imagen sea position:relative o position:absolute, la imagen cubrirá el contenedor. Sin embargo, no estará centrada.

Puede centrar fácilmente la imagen si sabe si se desbordará horizontalmente (set margin-left:-50%) o verticalmente (set margin-top:-50%). Puede ser posible usar CSS media queries (y algunas matemáticas) para averiguarlo.

 2
Author: Jeremy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 01:20:52

Lo que podría hacer es usar el atributo' style ' para agregar la imagen de fondo al elemento, de esa manera seguirá llamando a la imagen en el HTML, pero aún podrá usar el comportamiento css background-size: cover:

HTML:

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

CSS:

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

Así es como agrego el comportamiento background-size: cover a los elementos que necesito cargar dinámicamente en HTML. A continuación, puede utilizar clases css impresionantes como background-position: center. boom

 2
Author: Charlie Tupman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-30 16:00:56

Necesitaba emular background-size: contain, pero no pude usar object-fit debido a la falta de soporte. Mis imágenes tenían contenedores con dimensiones definidas y esto terminó funcionando para mí:

.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
Author: Gus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-07 22:22:03

Encontré una solución simple para emular tanto cover como contain, que es CSS puro, y funciona para contenedores con dimensiones dinámicas, y también no hace ninguna restricción en la relación de imagen.

Tenga en cuenta que si no necesita soportar IE, o Edge antes de 16, entonces es mejor usar object-fit.

Background-size: cover

.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>

El 1000% se usa aquí en caso de que el tamaño natural de la imagen sea mayor que el tamaño que se muestra. Por ejemplo, si la imagen es de 500x500, pero el contenedor es de solo 200x200. Con esta solución, la imagen se redimensionará a 2000x2000 (debido a min-width/min-height), luego se reducirá a 200x200 (debido a transform: scale(0.1)).

El factor x10 puede ser reemplazado por x100 o x1000, pero generalmente no es ideal tener una imagen de 2000x2000 renderizada en un div de 20x20. :)

Background-size: contain

Siguiendo el mismo principio, también se puede utilizar para emular 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>
 1
Author: Thiago Barcala,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-24 07:29:21

Para IE también necesita incluir la segunda línea-ancho: 100%;

.mydiv img {
    max-width: 100%;
    width: 100%;
}
 0
Author: фымышонок,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-21 15:11:58

No se me permite 'agregar un comentario', así que haciendo esto, pero sí, lo que Eru Penkman hizo es más o menos acertado, para que sea como una cubierta de fondo, todo lo que necesita hacer es cambiar

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

A

.wide-img{
    margin-left:-42%;
    height:100%;
}
.tall-img{
    margin-top:-42%;
    width:100%;
}
 0
Author: Asim Ramay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-17 06:24:48

Con CSS se puede simular object-fit: [cover|contain];. Es usar transform y [max|min]-[width|height]. no Es perfecto. Eso no funciona en un caso: si la imagen es más ancha y más corta que el contenedor.

.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
Author: mems,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-25 20:12:57

Sé que esto es viejo, sin embargo, muchas soluciones que veo anteriormente tienen un problema con la imagen/video que es demasiado grande para el contenedor, por lo que en realidad no actúa como una cubierta de tamaño de fondo. Sin embargo, decidí hacer "clases de utilidad" para que funcionara para imágenes y videos. Simplemente le das al contenedor la clase .media-cover-wrapper y el elemento multimedia en sí la clase .media-cover

Entonces tienes la siguiente jQuery:

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

Al llamarlo, asegúrese de cuidar de page redimensionamiento:

mediaCoverBounds();

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

Luego el siguiente CSS:

.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%);
}

Sí, puede requerir jQuery, pero responde bastante bien y actúa exactamente como background-size: cover y puede usarlo en imágenes y/o videos para obtener ese valor SEO adicional.

 0
Author: Secular12,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-12 18:12:58

Podemos hacer ZOOM. Podemos suponer que max 30% (o más hasta 100%) puede ser el efecto de zoom si la altura O el ancho de la imagen de aspecto es menor que la altura O el ancho deseados. Podemos ocultar el área de resto no necesario con desbordamiento: oculto.

.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%);
}

Esto ajustará imágenes con diferente ancho O alto.

 0
Author: rsharpy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-29 06:38:51
background:url('/image/url/') right top scroll; 
background-size: auto 100%; 
min-height:100%;

Encontró exactamente los mismos síntomas. arriba funcionó para mí.

 -1
Author: user2958520,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 00:42:11