¿Existe un equivalente al tamaño de fondo: cubrir y contener elementos de imagen?

241

Tengo un sitio con muchas páginas y diferentes imágenes de fondo, y las visualizo 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 (pantalla completa) en una página usando <img>elementos, y quiero que tengan las mismas propiedades que la background-image: cover;propiedad anterior (las imágenes no pueden mostrarse desde CSS, deben mostrarse desde el documento HTML).

Normalmente uso:

div.mydiv img {
    width: 100%;
}

O:

div.mydiv img {
    width: auto;
}

para hacer que la imagen sea completa y receptiva. Sin embargo, la imagen se reduce 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 manera de mostrar la imagen de la misma manera que lo background-size: coverhace?

Stormpat
fuente
Gran pregunta
wonsuc

Respuestas:

380

Solución n. ° 1: la propiedad de ajuste de objeto ( carece de compatibilidad con IE )

Solo ponte 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" />

Ver MDN - con respecto a object-fit: cover:

El contenido reemplazado se dimensiona para mantener su relación de aspecto mientras se llena todo el cuadro de contenido del elemento. Si la relación de aspecto del objeto no coincide con la relación de aspecto de su caja, entonces el objeto se recortará para ajustarse.

Además, vea esta demostración de Codepen que compara object-fit: coveraplicado a una imagen con background-size: coveraplicado a una imagen de fondo


Solución # 2 - Reemplace 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" />

Danield
fuente
3
En el momento de este comentario, el ajuste de objetos aún no es compatible con ninguna versión de Internet Explorer (incluso Edge). Sin embargo, está bajo consideración .
Mike Kormendy
3
el ajuste de objetos todavía no es compatible con IE. Me mantendría alejado si estuviera en el sitio de producción y le importen los usuarios de IE.
Travis Michael Heller
2
También puede agregar polyfill para # 1 para IE y Safari antiguo: github.com/bfred-it/object-fit-images
Valera Tumash
1
Cuidado con la segunda solución. Es mejor no confiar en vh en los navegadores móviles: nicolas-hoizey.com/2015/02/…
sudokai
1
@RoCk puedes encontrar cosas así en caniuse: caniuse.com/#search=background-att :) PD. Creo que todos podemos estar seguros de que IE nunca obtendrá soporte para esta función y como tampoco hay un polyfill, nosotros ' se atornilla o se atasca con los hacks JS / CSS hasta que MS decida que es hora de (finalmente) "asesinar" IE eliminándolo de Windows.
SidOfc
31

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>

Simón
fuente
99
Esto no replica el comportamiento de la cobertura, sino que recorta una sección centrada del src img. Consulte jsfiddle.net/sjt71j99/4 : el primer img es su cultivo, el siguiente es a través del tamaño de fondo: cubierta, es decir, lo que queremos, el tercero es el img original. Encontré que las imágenes de paisajes reemplazan min-height y min-width con max-height: 100%; para uso vertical ancho máximo: 100%. Sería bueno si hubiera una solución que funcionara para el paisaje o el retrato. ¿Algunas ideas? Esta es la mejor solución de navegador cruzado que he visto hasta ahora.
terraling
1
Tienes razón, no hace exactamente lo mismo, probé algunas cosas, pero parece que en realidad no puedes replicar la cubierta al 100%, funciona siempre que la imagen sea más pequeña que el contenedor en una dimensión aunque.
Simon
@terraling, sé que es un comentario antiguo, pero revisa mi respuesta . Utiliza transform para colocar el img en el centro.
Thiago Barcala
30

Suponiendo que puede hacer arreglos para tener un elemento contenedor que desea llenar, esto parece funcionar, pero se siente un poco difícil. En esencia, solo lo uso min/max-width/heighten un área más grande y luego escalo esa área 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>

Ulrich Schwarz
fuente
1
Completamente de acuerdo. Esta es la mejor solución de todas las anteriores para uso general.
Varis Vītols
Es genial. Me ayudó. Gracias
Raman Nikitsenka
14

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

Tenga en cuenta que si no necesita admitir IE o Edge antes de las 16, es mejor que use el ajuste de objetos.

tamaño de fondo: cubierta

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

Aquí se usa el 1000% 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 500x500, pero el contenedor es solo 200x200. Con esta solución, la imagen se redimensionará a 2000x2000 (debido al ancho mínimo / alto mínimo), luego se reducirá a 200x200 (debido atransform: scale(0.1) ).

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

tamaño de fondo: contener

Siguiendo el mismo principio, también puede usarlo 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>

Thiago Barcala
fuente
El truco de la escala ya se encuentra aquí https://stackoverflow.com/a/28771894/2827823 , por lo que no puedo ver el punto de publicar uno más, y también lo es transformen muchas de las respuestas
Ason el
Si desea ampliar con una explicación, actualice esa respuesta, ya que no hay necesidad de 2 con la misma solución
Ason el
1
Gracias por tu comentario @LGSon. No había visto esa respuesta antes, pero todavía creo que mi respuesta tiene su valor aquí. El enfoque es más o menos el mismo, pero en mi opinión, el mío se presenta de una manera un poco más limpia. Muchas otras respuestas aquí presentan la misma solución, y todas están incompletas (excepto la que vinculó). Entonces, si mi respuesta no debería estar aquí, tampoco deberían estar las otras.
Thiago Barcala
1
Descubrí que reduce la imagen en el navegador móvil Chrome en Android (probado en LG G3 y Samsung S9), no lo probé con Chrome en iOS, Firefox móvil en Android lo mostró correctamente.
Jecko
10

No , no puedes entenderlo bien, background-size:cover pero ...

Este enfoque es bastante cercano: 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/

roo2
fuente
3

Necesitaba emular background-size: contain, pero no pude usar object-fitdebido 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>

Gus
fuente
Puede usar min-height: 100%; max-height:100%;y obtener el equivalente a background-size: cover;
Chris Seufert
min-height: 100%; max-height:100%;no conservaría la relación de aspecto, por lo que no es exactamente un equivalente.
Reedyn
2

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

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

( violín )

Siempre que el elemento que contiene su imagen sea position:relativeo position:absolute, la imagen cubrirá el contenedor. Sin embargo, no estará centrado.

Puede centrar fácilmente la imagen si sabe si se desbordará horizontalmente (conjunto margin-left:-50%) o verticalmente (conjunto margin-top:-50%). Es posible utilizar consultas de medios CSS (y algunas matemáticas) para resolverlo.

Jeremy
fuente
2

Con CSS puedes simular object-fit: [cover|contain];. Es uso transformy [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>

mems
fuente
2

Lo que podría hacer es usar el atributo 'estilo' para agregar la imagen de fondo al elemento, de esa manera aún llamará a la imagen en el HTML pero aún podrá usar el comportamiento de tamaño de fondo: cubierta css:

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 elementos que necesito cargar dinámicamente en HTML. A continuación, puede utilizar impresionantes clases de CSS como background-position: center. auge

Charlie Tupman
fuente
1
Principalmente separación de preocupaciones, pero aquí hay algunas otras: programmers.stackexchange.com/a/271338
Daan
0

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

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

no tengo permitido 'agregar un comentario' al hacerlo, pero sí, lo que hizo Eru Penkman es bastante acertado, para que quede como fondo, todo lo que necesitas 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%;
}

Asim Ramay
fuente
0

Sé que esto es antiguo, sin embargo, muchas soluciones que veo arriba 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 con imágenes y videos. Simplemente le da al contenedor la clase .media-cover-wrapper y el elemento multimedia en sí mismo la clase .media-cover

Entonces tienes el 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 cambiar el tamaño de la página:

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 el tamaño de fondo: cubierta y puede usarlo en imágenes y / o videos para obtener ese valor adicional de SEO.

Secular12
fuente
0

Podemos adoptar el enfoque ZOOM. Podemos suponer que un máximo del 30% (o más hasta el 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 deseado. Podemos ocultar el resto del área no necesaria 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á las imágenes con diferentes anchuras o alturas.

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

encontré los mismos symptops exactos. arriba funcionó para mí.

usuario2958520
fuente