¿Cómo se estira una imagen para llenar un <div> manteniendo la relación de aspecto de la imagen?

201

Necesito hacer que esta imagen se estire al máximo tamaño posible sin desbordarla <div>ni torcerla.

No puedo predecir la relación de aspecto de la imagen, por lo que no hay forma de saber si usarla:

<img src="url" style="width: 100%;">

o

<img src="url" style="height: 100%;">

No puedo usar ambos (es decir, estilo = "ancho: 100%; altura: 100%;") porque eso estirará la imagen para que se ajuste al <div>.

El <div>tiene un conjunto tamaño por porcentaje de la pantalla, que también es impredecible.

Giffyguy
fuente
2
Si necesita que la imagen llene la altura o el ancho de las dimensiones correspondientes del div, solo puedo pensar en usar javascript. ¿Es algo que te gustaría explorar?
okw

Respuestas:

189

Actualización 2016:

El navegador moderno se comporta mucho mejor. Todo lo que debe hacer es establecer el ancho de la imagen al 100% ( demo )

.container img {
   width: 100%;
}

Como no conoce la relación de aspecto, tendrá que usar algunas secuencias de comandos. Así es como lo haría con jQuery ( demo ):

CSS

.container {
    width: 40%;
    height: 40%;
    background: #444;
    margin: 0 auto;
}
.container img.wide {
    max-width: 100%;
    max-height: 100%;
    height: auto;
}
.container img.tall {
    max-height: 100%;
    max-width: 100%;
    width: auto;
}​

HTML

<div class="container">
 <img src="http://i48.tinypic.com/wrltuc.jpg" />
</div>
<br />
<br />
<div class="container">
 <img src="http://i47.tinypic.com/i1bek8.jpg" />
</div>

Guión

$(window).load(function(){
 $('.container').find('img').each(function(){
  var imgClass = (this.width/this.height > 1) ? 'wide' : 'tall';
  $(this).addClass(imgClass);
 })
})
Mottie
fuente
¿Puede el usuario ver la imagen antes del cambio de tamaño? Alguien probó esto?
RayLoveless
La solución es casi correcta, solo tiene que invertir la altura y el ancho en el CSS: si la imagen es 'alta', entonces el ancho debe ser 100% no la altura (que será más grande y desbordante). Al revés para las fotos anchas.
mbritto
@mbritto: Tienes razón, tuve que cambiar el CSS a max-width / height y agregué una demostración
Mottie
@Mottie hay una manera de ajustar una imagen de tamaño 930 px de ancho a un contenedor de 960 px sin perder la calidad de la imagen
Vivek Dragon
15
¿Por qué es esta la respuesta aceptada? La pregunta es sobre las imágenes que son demasiado pequeñas para su contenedor. es decir, cómo se puede ampliar una imagen para llenar el ancho o la altura de su contenedor, sin alterar la relación de aspecto de la imagen. Además, en su demostración, eliminar las propiedades width:autoo height:autono afecta la visualización de sus imágenes. De hecho, de todas las propiedades que está aplicando a la imagen, solo max-width: 100%tiene algún efecto y solo afecta la imagen del paisaje. Pero lo más importante, su respuesta no ayuda a estirar una imagen pequeña para llenar un recipiente más grande.
matty
78

Hay una manera mucho más fácil de hacer esto usando solo CSSy HTML:

HTML:

<div class="fill"></div>

CSS:

.fill {
    overflow: hidden;
    background-size: cover;
    background-position: center;
    background-image: url('path/to/image.jpg');
}

Esto colocará su imagen como fondo y la estirará para que se ajuste al divtamaño sin distorsión.

Ryan
fuente
¿Es esto posible con un número indefinido de imágenes?
TrtG
background-size: cover;es la verdadera magia aquí, y es CSS3 pero tiene un soporte de navegador razonable en las versiones más recientes (ver: w3schools.com/cssref/css3_pr_background-size.asp )
Jon Kloske
1
Puede valer la pena incluir la url de la imagen en el HTML, para separar el estilo y los contenidos, es decir<div style="background-image: url('path/to/image.jpg');" class="fill"></div>
binaryfunt
background-size: cover no mantiene la relación de aspecto, se recortan partes de la imagen que no son proporcionales al elemento. Consulte aquí
Alex_Zhong
@Alex_Zhong, no entiendes la relación de aspecto. La relación de aspecto significa que la imagen no se estira en ninguna dirección (por lo que un círculo perfecto no se convertiría en un óvalo ni en ancho ni en alto). El recorte puede ser una parte necesaria para mantener la relación de aspecto (como lo es en el caso de uso del OP).
Jeremy Moritz
70

No es una solución perfecta, pero este CSS podría ayudar. El zoom es lo que hace que este código funcione, y el factor en teoría debería ser infinito para funcionar idealmente para imágenes pequeñas, pero 2, 4 u 8 funcionan bien en la mayoría de los casos.

#myImage {
    zoom: 2;  //increase if you have very small images

    display: block;
    margin: auto;

    height: auto;
    max-height: 100%;

    width: auto;
    max-width: 100%;
}
Prouda
fuente
1
Desearía que esto funcionara en Firefox. ¿Por qué no hay zoomamor de Firefox?
matty
1
Firefox todavía no se ha zoomimplementado, pero aquí está el enlace de error para referencia futura: bugzilla.mozilla.org/show_bug.cgi?id=390936
Adam Taylor
31

Si puede, use imágenes de fondo y establezca background-size: cover . Esto hará que el fondo cubra todo el elemento.

CSS

div {
  background-image: url(path/to/your/image.png);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
}

Si está atascado con el uso de imágenes en línea, hay algunas opciones. Primero hay

ajuste de objeto

Esta propiedad actúa sobre imágenes, videos y otros objetos similares a background-size: cover .

CSS

img {
  object-fit: cover;
}

Lamentablemente, el soporte del navegador no es tan bueno con IE hasta la versión 11 que no lo admite en absoluto. La siguiente opción usa jQuery

CSS + jQuery

HTML

<div>
  <img src="image.png" class="cover-image">
</div>

CSS

div {
  height: 8em;
  width: 15em;
}

Complemento jQuery personalizado

(function ($) {
  $.fn.coverImage = function(contain) {
    this.each(function() {
      var $this = $(this),
        src = $this.get(0).src,
        $wrapper = $this.parent();

      if (contain) {
        $wrapper.css({
          'background': 'url(' + src + ') 50% 50%/contain no-repeat'
        });
      } else {
        $wrapper.css({
          'background': 'url(' + src + ') 50% 50%/cover no-repeat'
        });
      }

      $this.remove();
    });

    return this;
  };
})(jQuery);

Usa el complemento como este

jQuery('.cover-image').coverImage();

Tomará una imagen, la configurará como imagen de fondo en el elemento contenedor de la imagen y eliminará la imgetiqueta del documento. Por último, podrías usar

CSS puro

Puede usar esto como una alternativa. La imagen se escalará para cubrir su contenedor, pero no se reducirá.

CSS

div {
  height: 8em;
  width: 15em;
  overflow: hidden;
}

div img {
  min-height: 100%;
  min-width: 100%;
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  display: block;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Espero que esto pueda ayudar a alguien, ¡feliz codificación!

daniels
fuente
Estaba buscando una solución CSS pura para que las imágenes llenen un contenedor determinado sin usar background-image & background-size y el código CSS aquí funciona muy bien para> = IE9 y navegadores modernos. Demostración de CodePen aquí
FLOQ Design, del
¡En Pure CSS , eliminé min-y cambié a width: 100%; height: 100%;y trabajo! ¡Una solución increíble! +1 ¡Gracias!
Guilherme Nascimento
1
background-size: containTambién es útil si no desea que ninguna de las imágenes se recorte.
Ponkadoodle
Puede agregar zoom:0.001a la solución CSS puro para reducir la escala.
Ivor Zhou
12

Actualización 2019.

Ahora puede usar la object-fitpropiedad css que acepta los siguientes valores:fill | contain | cover | none | scale-down

https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

Como ejemplo, podría tener un contenedor que contenga una imagen.

<div class="container">
    <img src="" class="container_img" />
</div>

.container {
    height: 50px;
    width: 50%;

.container_img {
    height: 100%;
    width: 100%;
    object-fit: cover;
Ed Stennett
fuente
7

Eso es imposible con solo HTML y CSS, o al menos salvajemente exótico y complicado. Si está dispuesto a incluir JavaScript, aquí hay una solución con jQuery:

$(function() {
    $(window).resize(function() {
        var $i = $('img#image_to_resize');
        var $c = $img.parent();
        var i_ar = $i.width() / $i.height(), c_ar = $c.width() / $c.height();            
        $i.width(i_ar > c_ar ? $c.width() : $c.height() * (i_ar));
    });
    $(window).resize();
});

Eso cambiará el tamaño de la imagen para que siempre se ajuste al elemento principal, independientemente de su tamaño. Y a medida que se vincula al $(window).resize()evento, cuando el usuario cambia el tamaño de la ventana, la imagen se ajustará.

Esto no intenta centrar la imagen en el contenedor, eso sería posible, pero supongo que eso no es lo que buscas.

Tatu Ulmanen
fuente
44
Supongo $ img.parent (); realmente debería ser $ i.parent ();
Jimbo Jonny
5

Establece el ancho y la altura del containerdiv externo . Luego use el siguiente estilo en img:

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

Esto te ayudará a mantener una relación de aspecto de tu img

Chintan Bhatt
fuente
66
no llenará el div.
Sven van den Boogaart
5

Si desea establecer un ancho o alto máximo (para que no sea muy grande) mientras mantiene la relación de aspecto de las imágenes, puede hacer esto:

img{
   object-fit: contain;
   max-height: 70px;
}
Bohao LI
fuente
4

Encontré esta pregunta buscando un problema similar. Estoy creando una página web con un diseño receptivo y el ancho de los elementos colocados en la página se establece en un porcentaje del ancho de la pantalla. La altura se establece con un valor vw.

Como estoy agregando publicaciones con PHP y un backend de base de datos, CSS puro estaba fuera de discusión. Sin embargo, encontré la solución jQuery / javascript un poco problemática, así que se me ocurrió una solución ordenada (al menos eso creo).

HTML (o php)

div.imgfill {
  float: left;
  position: relative;
  background-repeat: no-repeat;
  background-position: 50%  50%;
  background-size: cover;
  width: 33.333%;
  height: 18vw;
  border: 1px solid black; /*frame of the image*/
  margin: -1px;
}
<div class="imgfill" style="background-image:url(source/image.jpg);">
  This might be some info
</div>
<div class="imgfill" style="background-image:url(source/image2.jpg);">
  This might be some info
</div>
<div class="imgfill" style="background-image:url(source/image3.jpg);">
  This might be some info
</div>

Al usar style = "" es posible que PHP actualice mi página dinámicamente y el estilo CSS junto con style = "" terminará en una imagen perfectamente cubierta, escalada para cubrir la etiqueta div dinámica.

Christian Jensen
fuente
4

Para hacer que esta imagen se extienda al máximo tamaño posible sin desbordarse ni torcerla.

Aplicar...

img {
  object-fit: cover;
  height: -webkit-fill-available;
}

estilos a la imagen.

frijoles
fuente
3

Usando este método, puede completar su div con la proporción variable de divs e imágenes.

jQuery:

$(window).load(function(){
   $('body').find(.fillme).each(function(){
      var fillmeval = $(this).width()/$(this).height();
      var imgval = $this.children('img').width()/$this.children('img').height();
      var imgClass;
      if(imgval > fillmeval){
          imgClass = "stretchy";
      }else{
          imgClass = "stretchx";
      }
      $(this).children('img').addClass(imgClass);
   });
});

HTML:

<div class="fillme">
   <img src="../images/myimg.jpg" />
</div>

CSS:

.fillme{
  overflow:hidden;
}
.fillme img.stretchx{
  height:auto;
  width:100%;
}
.fillme img.stretchy{
  height:100%;
  width:auto;
}
usuario1994142
fuente
3

Esto hizo el truco para mí

div img {
    width: 100%;
    min-height: 500px;
    width: 100vw;
    height: 100vh;
    object-fit: cover;
}
Developer_D
fuente
2

Si trabaja con la etiqueta IMG, es fácil.

Yo hice esto:

<style>
        #pic{
            height: 400px;
            width: 400px;
        }
        #pic img{
            height: 225px;               
            position: relative;
            margin: 0 auto;
        }
</style>

<div id="pic"><img src="images/menu.png"></div>

$(document).ready(function(){
            $('#pic img').attr({ 'style':'height:25%; display:none; left:100px; top:100px;' })
)}

pero no encontré cómo hacerlo funcionar con #pic {background: url (img / menu.png)} Enyone? Gracias

aleXela
fuente
Hice un cambio y encontré una respuesta a mi problema. No, eso ayudará a alguien. background-image: url (images / menu.png); repetición de fondo: sin repetición; posición: absoluta; tamaño de fondo: 300 px; altura: 100%; ancho: 100%; y puede cambiar el valor del tamaño de fondo usando javascript o jquery (.attr ({'style': 'background-size: 150px auto; left: 50px; top: 50px;'}))
aleXela
2

Tuve un problema similar. Lo resolví solo con CSS .

Básicamente Object-fit: cover ayuda a lograr la tarea de mantener la relación de aspecto mientras coloca una imagen dentro de un div.

Pero el problema era que Object-fit: coverno funcionaba en IE y estaba tomando 100% de ancho y 100% de altura y la relación de aspecto estaba distorsionada. En otras palabras, el efecto de zoom de la imagen no estaba allí, lo que estaba viendo en cromo.

El enfoque que tomé fue colocar la imagen dentro del contenedor con absoluta y luego colocarla justo en el centro usando la combinación:

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

Una vez que está en el centro, le doy a la imagen,

// For vertical blocks (i.e., where height is greater than width)
height: 100%;
width: auto;

// For Horizontal blocks (i.e., where width is greater than height)
height: auto;
width: 100%;

Esto hace que la imagen obtenga el efecto de Object-fit: cover.


Aquí hay una demostración de la lógica anterior.

https://jsfiddle.net/furqan_694/s3xLe1gp/

Esta lógica funciona en todos los navegadores.

Furqan Rahamath
fuente
1

HTML:

<style>
#foo, #bar{
    width: 50px; /* use any width or height */
    height: 50px;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
}
</style>

<div id="foo" style="background-image: url('path/to/image1.png');">
<div id="bar" style="background-image: url('path/to/image2.png');">

JSFiddle

... Y si desea establecer o cambiar la imagen (usando #foo como ejemplo):

jQuery:

$("#foo").css("background-image", "url('path/to/image.png')");

JavaScript:

document.getElementById("foo").style.backgroundImage = "url('path/to/image.png')";
Patch92
fuente
1

Muchas de las soluciones que se encuentran aquí tienen algunas limitaciones: algunas no funcionan en IE (ajuste de objeto) o navegadores más antiguos, otras soluciones no escalan las imágenes (solo lo reducen), muchas soluciones no admiten el cambio de tamaño de la ventana y muchas son no genérico, espere una resolución o diseño fijo (vertical u horizontal)

Si usar javascript y jquery no es un problema, tengo esta solución basada en el código de @Tatu Ulmanen. Solucioné algunos problemas y agregué código en caso de que la imagen se cargara dinámicamente y no estuviera disponible al principio. Básicamente, la idea es tener dos reglas CSS diferentes y aplicarlas cuando sea necesario: una cuando la limitación es la altura, por lo que debemos mostrar barras negras a los lados, y la regla CSS cuando la limitación es el ancho, por lo que debemos mostrar barras negras en la parte superior / inferior.

function applyResizeCSS(){
    var $i = $('img#imageToResize');
    var $c = $i.parent();
    var i_ar = Oriwidth / Oriheight, c_ar = $c.width() / $c.height();  
    if(i_ar > c_ar){
        $i.css( "width","100%");
        $i.css( "height","auto");          
    }else{
        $i.css( "height","100%");
        $i.css( "width","auto");
    }
}   
var Oriwidth,Oriheight;
$(function() {
    $(window).resize(function() {
        applyResizeCSS();
    });

    $("#slide").load(function(){
        Oriwidth  = this.width,
        Oriheight = this.height; 
        applyResizeCSS();
    }); 

    $(window).resize();
}); 

Para un elemento HTML como:

<img src="images/loading.gif" name="imageToResize" id="imageToResize"/> 
jolumg
fuente