¿Cómo puedo llenar un div con una imagen mientras la mantengo proporcional?

120

Encontré este hilo: ¿Cómo se estira una imagen para llenar un <div> mientras se mantiene la relación de aspecto de la imagen? - eso no es del todo lo que quiero.

Tengo un div con cierto tamaño y una imagen dentro de él. Quiero siempre llene el siguiente div con la imagen sin tener en cuenta si la imagen es horizontal o vertical. Y no importa si la imagen está cortada (el div en sí tiene un desbordamiento oculto).

Entonces, si la imagen es retrato, quiero widthque sea 100%y height:autoasí se mantiene en proporción. Si la imagen es apaisada quiero heightque sea 100%y width to beauto`. Suena complicado, ¿verdad?

<div class="container">
   <img src="some-image.jpg" alt="Could be portrait or landscape"/>
</div>

Como no sé cómo hacerlo, simplemente creé una imagen rápida de lo que quiero decir. Ni siquiera puedo describirlo adecuadamente.

ingrese la descripción de la imagen aquí

Entonces, supongo que no soy el primero en preguntar esto. Sin embargo, no pude encontrar una solución a esto. Tal vez haya alguna nueva forma CSS3 de hacer esto, estoy pensando en flex-box. ¿Alguna idea? ¿Quizás es incluso más fácil de lo que espero que sea?

mate
fuente
¿Por qué quiere usar css3 cuando todavía puede hacerlo fácilmente con javascript? Ir con js matey ..
GautamJeyaraman
1
Sin probar, pero ¿podría intentar establecer la altura mínima y el ancho mínimo al 100%? Eso debería al menos llenar el cuadro y mantenerlo en proporción
chrisbulmer

Respuestas:

150

Si entiendo correctamente lo que quiere, puede dejar los atributos de ancho y alto fuera de la imagen para mantener la relación de aspecto y usar flexbox para centrarlo por usted.

.fill {
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden
}
.fill img {
    flex-shrink: 0;
    min-width: 100%;
    min-height: 100%
}
<div class="fill">
    <img src="https://lorempizza.com/320/240" alt="" />
</div>

JSFiddle aquí

Probé esto con éxito en IE9, Chrome 31 y Opera 18. Pero no se probó ningún otro navegador. Como siempre, debe considerar sus requisitos particulares de soporte.

Isius
fuente
En IE9, la imagen no está centrada vertical u horizontalmente con este método, está alineada en la parte superior e izquierda. i59.tinypic.com/ouo77s.png
Mike Kormendy
1
Esto tiene un problema en el iPad, parece que safari estira la imagen al 100% de su altura, pero no conserva la propiedad de ancho mínimo.
Sean
14
Esto parece aumentar la escala de las imágenes pequeñas para llenarlas, pero no reducirlas para ajustarlas. Al menos cuando utilizo una imagen grande, solo muestra una pequeña porción de ella.
Johncl
12
Para tener una imagen grande reducida para que quepa, utilicé lo siguiente en la imagen:.fill img { min-height:100%; min-width: 100%; object-fit: cover; }
Peter G
superhéroe! : D
Garis M Suero
47

Es un poco tarde, pero tuve el mismo problema y finalmente lo resolví con la ayuda de otra publicación de stackoverflow ( https://stackoverflow.com/a/29103071 ).

.img {
   object-fit: cover;
   width: 50px;
   height: 100px;
}

Espero que esto todavía ayude a alguien.

Ps: también funciona junto con las propiedades css max-height , max-width , min-width y min-height . Es especialmente útil con el uso de unidades de longitud como 100% o 100vh / 100vw para llenar el contenedor o toda la ventana del navegador.

Hermilton
fuente
¿Es esta una solución para navegadores cruzados?
Candlejack
1
objeto de ajuste: cubierta; ¡Funciona genial! Información del navegador (no funciona en IE): css-tricks.com/almanac/properties/o/object-fit Solución alternativa para IE: medium.com/@primozcigler/… MS está trabajando para implementarlo: developer.microsoft.com / en-us / microsoft-edge / platform / status /…
Kaah
Supongo que agregar una object-positionregla a esta clase será útil aquí. Solo una nota al margen.
Taha Paksu
8

Una vieja pregunta pero merece una actualización ya que ahora hay una forma.

La respuesta correcta basada en CSS es usar object-fit: cover, que funciona como background-size: cover. El posicionamiento se realizará por object-positionatributo, que por defecto es centrado.

Pero no hay soporte para él en ningún navegador IE / Edge, o Android <4.4.4. Además, object-positionno es compatible con Safari, iOS u OSX. Los polyfills existen, las imágenes de ajuste de objetos parecen dar el mejor soporte.

Para obtener más detalles sobre cómo funciona la propiedad, consulte el artículo Trucos de CSS sobreobject-fit para obtener una explicación y una demostración.

holista
fuente
8

Esto debería hacerlo:

img {    
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
}
maksim1
fuente
Funciona bastante bien para mí, en mi caso solo necesitaba agregar la posición: absoluta y superior: 0, y también algo de índice z
byroncorrales
7

Todas las respuestas a continuación tienen un ancho y alto fijos, lo que hace que la solución "no responda".

Para lograr el resultado pero mantener la imagen receptiva, utilicé lo siguiente:

  1. Dentro del contenedor coloque una imagen gif transparente con la proporción deseada
  2. Dar una etiqueta de imagen de fondo css en línea con la imagen que desea cambiar de tamaño y recortar

HTML:

<div class="container">
    <img style="background-image: url("https://i.imgur.com/XOmNCwY.jpg");" src="img/blank.gif">
</div> 


.container img{
   width: 100%;
   height: auto;
   background-size: cover;
   background-repeat: no-repeat;
   background-position: center;
}​
Artur Klassen
fuente
Usé background-image para todo el sitio web de mi empresa de portafolio de diseño para poder tener background-size: cover. Ahora el SEO de mi imagen está en mal estado porque Google no reconoce las imágenes de fondo. Ojalá lo hubiera codificado de otra manera.
Alex Banman
5

Puede lograr esto usando las propiedades de css flex. Consulte el código a continuación

.img-container {
  border: 2px solid red;
  justify-content: center;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  
}
.img-container .img-to-fit {
  flex: 1;
  height: 100%;
}
<div class="img-container">
  <img class="img-to-fit" src="https://images.pexels.com/photos/8633/nature-tree-green-pine.jpg" />
</div>

Sandeep K Nair
fuente
1
Esto funciona SOLO si elimina las propiedades de ancho y alto como se menciona en algunas de las otras respuestas.
Chiwda
3

Considere usar background-size: cover(IE9 +) junto con background-image. Para IE8-, hay un polyfill .

Marat Tanalin
fuente
¿No requiere esto una URL de fondo? ¿Puedes elaborar más? ¿Puede esto funcionar con <img src = "" /> como se indica en la pregunta?
harsimranb
@harsimranb Por supuesto, background-sizetiene sentido únicamente con background-imageespecificar también (he actualizado mi respuesta en consecuencia). No se aplica a los IMGelementos.
Marat Tanalin
Esta es la mejor respuesta. Es simple y tiene un buen soporte de navegador. Todas las demás soluciones son muy complejas o no funcionan en IE (9).
JoostS
1

Prueba esto:

img {
  position: relative;
  left: 50%;
  min-width: 100%;
  min-height: 100%;
  transform: translateX(-50%);
}

Espero que esto ayude

Landerqvist
fuente
1

Puedes usar div para lograr esto. sin etiqueta img :) espero que esto ayude.

.img{
	width:100px;
	height:100px;
	background-image:url('http://www.mandalas.com/mandala/htdocs/images/Lrg_image_Pages/Flowers/Large_Orange_Lotus_8.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
.img1{
	width:100px;
	height:100px;
	background-image:url('https://images.freeimages.com/images/large-previews/9a4/large-pumpkin-1387927.jpg');
	background-repeat:no-repeat;
	background-position:center center;
	border:1px solid red;
	background-size:cover;
}
<div class="img">	
</div>
<div class="img1">	
</div>

Sivasakthivel Kalaiarasu
fuente
1

La única forma en que logré el escenario del "mejor caso" descrito fue poniendo la imagen como fondo:

<div class="container"></div>
.container {
    width: 150px;
    height: 100px;
    background-image: url("http://i.stack.imgur.com/2OrtT.jpg");
    background-size: cover;
    background-repeat: no-repeat;
    background-position: 50% 50%;
}​
David Schumann
fuente
1

Aquí hay una respuesta con soporte para IE usando object-fit para que no pierda la proporción

Usando un simple fragmento de código JS para detectar si object-fites compatible y luego reemplazar el imgpor unsvg

//for browsers which doesn't support object-fit (you can use babel to transpile to ES5)

if ('objectFit' in document.documentElement.style === false) {
  document.addEventListener('DOMContentLoaded', () => {
    Array.prototype.forEach.call(document.querySelectorAll('img[data-object-fit]'), image => {
      (image.runtimeStyle || image.style).background = `url("${image.src}") no-repeat 50%/${image.currentStyle ? image.currentStyle['object-fit'] : image.getAttribute('data-object-fit')}`
      image.src = `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='${image.width}' height='${image.height}'%3E%3C/svg%3E`
    })
  })
}
img {
  display: inline-flex;
  width: 175px;
  height: 175px;
  margin-right: 10px;
  border: 1px solid red
}

/*for browsers which support object fit */

[data-object-fit='cover'] {
  object-fit: cover
}

[data-object-fit='contain'] {
  object-fit: contain
}
<img data-object-fit='cover' src='//picsum.photos/1200/600' />
<img data-object-fit='contain' src='//picsum.photos/1200/600' />
<img src='//picsum.photos/1200/600' />


Nota: también hay algunos object-fitpolyfills que haránobject-fit funcionarán.

Aquí están algunos ejemplos:

dippas
fuente
0

Aquí tienes mi ejemplo de trabajo. He usado un truco que consiste en configurar la imagen como fondo del contenedor div con background-size: cover y background-position: center center

He colocado la imagen con ancho: 100% y opacidad: 0 haciéndola invisible. Tenga en cuenta que estoy mostrando mi imagen solo porque tengo un interés especial en llamar al evento de clic del niño.

Tenga en cuenta que aunque estoy usando angular, es completamente irrelevante.

<div class="foto-item" ng-style="{'background-image':'url('+foto.path+')'}">
    <img class="materialboxed" ng-class="foto.picid" ng-src="{{foto.path}}" style="opacity: 0;filter: alpha(opacity=0);" width="100%" onclick="$('.materialboxed')/>
 </div>
<style>
.foto-item {
height: 75% !important;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow:hidden;
background-size: cover;
background-position: center center;
}
</style>

El resultado es el que defines como óptimo en todos los casos

Cadáveres de Noel
fuente
0

Los valores de propiedad object-fit: covery CSS object-position: left centerahora abordan este problema.

Ingeniería inversa
fuente
0

.image-wrapper{
    width: 100px;
    height: 100px;
    border: 1px solid #ddd;
}
.image-wrapper img {
    object-fit: contain;
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
}
<div class="image-wrapper">
  <img src="">
</div>

Yaseen
fuente
-3

Simplemente corrija la altura de la imagen y proporcione ancho = automático

img{
    height: 95vh;
    width: auto;
}
Sarthak
fuente