Tamaño de imagen CSS, ¿cómo rellenar, no estirar?

415

Tengo una imagen y quiero establecer un ancho y alto específicos (en píxeles)

Pero si configuro el ancho y la altura usando css ( width:150px; height:100px), la imagen se estirará y puede ser fea.

¿Cómo rellenar imágenes a un tamaño específico usando CSS y sin estirarlo ?

Ejemplo de imagen de relleno y estiramiento:

Imagen original:

Original

Imagen estirada:

Estirado

Imagen llena:

Lleno

Tenga en cuenta que en el ejemplo de la imagen Rellena arriba: primero, la imagen se redimensiona a 150x255 (relación de aspecto mantenida), y luego, se recorta a 150x100.

Mahdi Ghiasi
fuente
Intente simplemente configurar widthy heightdebería ajustar en consecuencia
NewInTheBusiness
3
Se estira la imagen. mira esto: jsfiddle.net/D7E3E
Mahdi Ghiasi
¡Se necesita una parte de la imagen que no cambia de tamaño!
Ali Ben Messaoud
3
Chris Coyier también tiene algunas buenas soluciones para esto: css-tricks.com/perfect-full-page-background-image
ambiguousmouse
1
MUY IMPORTANTE: esta es una práctica increíblemente mala para fines de SEO. Si lo está utilizando como imagen de fondo, entonces funciona bien, pero si desea que Google encuentre la imagen, NO se indexará si solo se trata de una imagen de fondo.
Alex Banman el

Respuestas:

395

Si desea utilizar la imagen como fondo CSS, existe una solución elegante. Simplemente use covero containen la background-sizepropiedad CSS3.

.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%;
}
<div class="container"></div>

Mientras que coverle dará una imagen ampliada, containle dará una imagen reducida. Ambos preservarán la relación de aspecto de píxeles.

http://jsfiddle.net/uTHqs/ (usando portada)

http://jsfiddle.net/HZ2FT/ (usando contener)

Este enfoque tiene la ventaja de ser amigable con las pantallas Retina según la guía rápida de Thomas Fuchs.

Vale la pena mencionar que la compatibilidad del navegador para ambos atributos excluye IE6-8.

Marcelo De Polli
fuente
1
Como puede cambiar el tamaño de la imagen únicamente en el CSS, esto le permite usar una imagen grande y luego reducirla de acuerdo con la densidad de píxeles de cada dispositivo mediante el uso de consultas de medios.
Marcelo De Polli
1
¿Podría explicar por qué en este caso la posición de fondo parece indicar la posición del centro de la imagen en lugar de su esquina superior izquierda? ¿Es consecuencia del tamaño del fondo: cubierta?
matteo
1
el mío solo cubre todo el DIV expandiendo la imagen. No veo que termine la curva.
SearchForKnowledge
3
Lo que es background-repeat: no-repeat;para? Si la imagen cubre su contenedor, no se repetirá de todos modos.
lurkit
3
'background-position' también podría establecerse en 'center center'. ej .: .container {... posición de fondo: centro centro; }
Leo Ribeiro
556

Puede usar la propiedad css object-fit.

.cover {
  object-fit: cover;
  width: 50px;
  height: 100px;
}
<img src="http://i.stack.imgur.com/2OrtT.jpg" class="cover" width="242" height="363" />

Ver ejemplo aquí

Hay un polyfill para IE: https://github.com/anselmh/object-fit

afonsoduarte
fuente
11
Es interesante ver que esto también se puede hacer con imgetiquetas (no solo con el background-imagemétodo descrito en la respuesta anterior). Gracias :)
Mahdi Ghiasi
44
Al considerar esto como una opción, tenga en cuenta que object-fit no es compatible con muchos navegadores .
joshreesjones
2
Lamentablemente, background-sizerara vez es una solución viable en mis proyectos. Es menos probable que reciba algún beneficio de SEO y no puede proporcionar una etiqueta ALT, título, etc. para acompañar la imagen donde desee proporcionar contexto adicional para lectores de pantalla.
Markus
3
Esto es genial, pero no hay soporte para IE. Ninguno de los polyfills funciona más.
Jake
3
Solo usando lo object-fit: cover;hace. Muchas gracias
Luka
67

Mejora en la respuesta anterior por @afonsoduarte ( NO la aceptada) .
en caso de que estés usando bootstrap


Hay tres diferencias:

  1. Proporcionando width:100%en el estilo.
    Esto es útil si está utilizando bootstrap y desea que la imagen estire todo el ancho disponible.

  2. La especificación de la heightpropiedad es opcional. Puede eliminarla / conservarla según lo necesite

    .cover {
       object-fit: cover;
       width: 100%;
       /*height: 300px;  optional, you can remove it, but in my case it was good */
    }
  3. Por cierto, NO es necesario proporcionar los atributos heighty widthen el imageelemento porque el estilo los anulará.
    entonces es suficiente escribir algo como esto.

    <img class="cover" src="url to img ..."  />
Hakan Fıstık
fuente
1
Exactamente lo que estaba buscando.
francis lanthier
1
Necesitas un beso!
Qin Wang
Object-Fit no funciona con IE?
bgcode
1
es 2020, creo que es un buen momento para abandonar IE
Hakan Fıstık
56

La única forma real es tener un contenedor alrededor de su imagen y usar overflow:hidden:

HTML

<div class="container"><img src="ckk.jpg" /></div>

CSS

.container {
    width: 300px;
    height: 200px;
    display: block;
    position: relative;
    overflow: hidden;
}

.container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

Es un dolor en CSS hacer lo que quieres y centrar la imagen, hay una solución rápida en jquery como:

var conHeight = $(".container").height();
var imgHeight = $(".container img").height();
var gap = (imgHeight - conHeight) / 2;
$(".container img").css("margin-top", -gap);

http://jsfiddle.net/x86Q7/2/

Dominic Green
fuente
1
Gracias. funcionó, pero recorta la imagen desde arriba . (vea esto: jsfiddle.net/x86Q7 ) ¿No hay alguna forma de recortar la imagen desde el centro ?
Mahdi Ghiasi
1
@MahdiGhiasi: ¡Cambie las propiedades superior e izquierda en .container img css !!
Ali Ben Messaoud
Puedo establecer una margin-topimagen por ejemplo 50px(ver esto: jsfiddle.net/x86Q7/1 ), pero ¿Cómo recortarla del centro real ? (¿Sin jQuery?)
Mahdi Ghiasi
2
Ahh lo siento, no vi tu comentario, pero agregué el jquery por si acaso :)
Dominic Green
1
¡Gran solución! Para mí, el relleno vertical era más importante que el horizontal, así que solo tuve que cambiar "ancho: 100%" a "altura: 100%" para la clase '.container img'. ¡Gracias!
Considera
26

Solución CSS sin JS y sin imagen de fondo:

Método 1 "margen automático" (IE8 + - ¡NO FF!):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  position:absolute; 
  top:0; 
  bottom:0; 
  margin: auto;
  width:100%;
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/

Método 2 "transformar" (IE9 +):

div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}

div img{
  position:absolute; 
  width:100%;
  top: 50%;
  -ms-transform: translateY(-50%);
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}
<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
  <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>

http://jsfiddle.net/5xjr05dt/1/

El método 2 puede usarse para centrar una imagen en un contenedor de ancho / alto fijo. Ambos pueden desbordarse, y si la imagen es más pequeña que el contenedor, seguirá estando centrada.

http://jsfiddle.net/5xjr05dt/3/

Método 3 "doble envoltura" (IE8 + - ¡NO FF!):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
    display: table;
    left: 50%;
}
.inner img {
    display: block;
    border: 1px solid blue; /* just for example */
    position: relative;
    right: 50%;
    opacity: .5; /* just for example */
}
<div class="outer">
  <div class="inner">
     <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/5/

Método 4 "doble envoltura Y doble imagen" (IE8 +):

.outer{
  width:150px; 
  height:100px; 
  margin: 200px auto; /* just for example */
  border: 1px solid red; /* just for example */
  /* overflow: hidden;	*/ /* TURN THIS ON */
  position: relative;
}
.inner { 
    border: 1px solid green; /* just for example */
    position: absolute;
    top: 50%;
    bottom: 0;
    display: table;
    left: 50%;
}
.inner .real_image {
    display: block;
    border: 1px solid blue; /* just for example */
    position: absolute;
    bottom: 50%;
    right: 50%;
    opacity: .5; /* just for example */
}

.inner .placeholder_image{
  opacity: 0.1; /* should be 0 */
}
<div class="outer">
  <div class="inner">
    <img class="real_image" src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
    <img class="placeholder_image"  src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
  </div>
</div>

http://jsfiddle.net/5xjr05dt/26/

  • El método 1 tiene un soporte ligeramente mejor: ¡debe establecer el ancho O la altura de la imagen!
  • Con los prefijos, el método 2 también tiene un soporte decente (desde ie9 en adelante) - ¡El método 2 no tiene soporte en Opera mini!
  • El método 3 usa dos envoltorios: puede desbordar el ancho Y la altura.
  • El Método 4 utiliza una imagen doble (una como marcador de posición), lo que proporciona una sobrecarga de ancho de banda adicional, pero incluso mejor compatibilidad con el navegador cruzado.

Los métodos 1 y 3 no parecen funcionar con Firefox

JT Houtenbos
fuente
Este es el único que realmente funciona (menos soluciones js). ¡Gracias!
Jake
Se limita a desbordar altura o anchura, pero es una solución interesante.
Jake
1
@Jake: es posible desbordar el ancho Y la altura con el método 2 anterior: vea mi respuesta actualizada con el violín adicional.
JT Houtenbos
Si. Definitivamente es una gran respuesta. Voy a perder el tiempo un poco más. Era un poco peculiar para una imagen más ancha que más alta que necesitaba ser receptiva, pero hay muchas aplicaciones para esto.
Jake
1
@Jake - Genial - Encontré un tercer método para centrar horizontalmente. Extendí este método para admitir también el centrado vertical. Publicaré mi adición como un tercer método anterior. Parece que es una prueba de IE7 + (incluso más baja posiblemente). Aquí está la respuesta original: stackoverflow.com/questions/3300660/…
JT Houtenbos
10

Otra solución es colocar la imagen en un contenedor con el ancho y la altura deseados. Con este método, no tendría que establecer la imagen como imagen de fondo de un elemento.

Luego puede hacer esto con una imgetiqueta y simplemente establecer un ancho máximo y una altura máxima en el elemento.

CSS:

.imgContainer {
    display: block;
    width: 150px; 
    height: 100px;
}

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

HTML:

<div class='imgContainer'>
    <img src='imagesrc.jpg' />
</div>

Ahora, cuando cambie el tamaño del contenedor, la imagen crecerá automáticamente tanto como sea posible sin salir de los límites o distorsionarse.

Si desea centrar la imagen vertical y horizontalmente, puede cambiar el contenedor css a:

.imgContainer {
    display: table-cell;
    width: 150px; 
    height: 100px;
    text-align: center;
    vertical-align: middle;
}

Aquí hay un JS Fiddle http://jsfiddle.net/9kUYC/2/

earl3s
fuente
No es lo mismo que la cobertura en CSS, donde una de las dimensiones resultantes siempre está más allá del 100% (o igual en el caso límite)
Miroshko
No, esta solución se asegura de que nunca se extienda más allá del 100%, de eso se trata parte de la pregunta. No querían que la imagen se distorsionara o creciera más allá de las dimensiones originales.
earl3s
3
La pregunta era "Cómo llenar" con un ejemplo de imagen llena, que obviamente está recortada.
Miroshko
Pero, ¿qué sucede si necesita que la imagen responda? Definir un ancho y una altura específicos no va a funcionar 😕
Ricardo Zea
2
Era lo que necesitaba. ¡Gracias!
Nico Rodsevich
5

Partiendo de la respuesta de @Dominic Green usando jQuery, aquí hay una solución que debería funcionar para imágenes que son más anchas que altas o más altas que anchas.

http://jsfiddle.net/grZLR/4/

Probablemente haya una forma más elegante de hacer JavaScript, pero esto funciona.

function myTest() {
  var imgH = $("#my-img").height();
  var imgW = $("#my-img").width();
  if(imgW > imgH) {
    $(".container img").css("height", "100%");
    var conWidth = $(".container").width();
    var imgWidth = $(".container img").width();
    var gap = (imgWidth - conWidth)/2;
    $(".container img").css("margin-left", -gap);
  } else {
    $(".container img").css("width", "100%");
    var conHeight = $(".container").height();
    var imgHeight = $(".container img").height();
    var gap = (imgHeight - conHeight)/2;
    $(".container img").css("margin-top", -gap);
  }
}
myTest();
ramdog
fuente
5
  • No utiliza el fondo css
  • Solo 1 div para recortarlo
  • Redimensionado al ancho mínimo que mantener la relación de aspecto correcta
  • Recorte desde el centro (vertical y horizontalmente, puede ajustarlo con la parte superior, izquierda y transformación)

Tenga cuidado si está usando un tema o algo, a menudo declaran img max-width al 100%. Tienes que hacer ninguno. Pruébalo :)

https://jsfiddle.net/o63u8sh4/

<p>Original:</p>
<img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>

<p>Wrapped:</p>
<div>
    <img src="http://i.stack.imgur.com/2OrtT.jpg" alt="image"/>
</div>


div{
  width:150px; 
  height:100px; 
  position:relative;
  overflow:hidden;
}
div img{
  min-width:100%;
  min-height:100%;
  height:auto;
  position:relative;
  top:50%;
  left:50%;
  transform:translateY(-50%) translateX(-50%);
}
dmegatool
fuente
Esta es la respuesta que estaba buscando.
Marcos Buarque
Esto es lo que quería hacer durante mucho tiempo, gracias;)
Jefe COTIGA
4

Ayudé a construir un complemento jQuery llamado Fillmore , que maneja los background-size: covernavegadores que lo admiten, y tiene una cuña para aquellos que no lo hacen. ¡Dale un vistazo!

Aidan Feldman
fuente
4

Creo que es bastante tarde para esta respuesta. De todos modos espero que esto ayude a alguien en el futuro. Me enfrenté al problema de posicionar las tarjetas en angular. Se muestran tarjetas para una variedad de eventos. Si el ancho de la imagen del evento es grande para la tarjeta, la imagen debe mostrarse recortando desde dos lados y una altura del 100%. Si la altura de la imagen es larga, la parte inferior de las imágenes se recorta y el ancho es del 100%. Aquí está mi solución css pura para esto:

ingrese la descripción de la imagen aquí

HTML:

 <span class="block clear img-card b-b b-light text-center" [ngStyle]="{'background-image' : 'url('+event.image+')'}"></span>

CSS

.img-card {
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
width: 100%;
overflow: hidden;
}
Nodirabegimxonoyim
fuente
No puedo entender cómo funciona esto, pero lo hace. Debe colocar el tramo absolutamente arriba: 0; derecha: 0; abajo: 0; izquierda: 0 dentro del padre relativamente posicionado para acotarlo.
Mike
Gracias por sus comentarios querido Mike, estoy feliz si esto fue útil. ¿Quieres que actualice la respuesta con tu comentario?
Nodirabegimxonoyim
3

Intenta algo como esto: http://jsfiddle.net/D7E3E/4/

Usar un contenedor con desbordamiento: oculto

EDITAR: @Dominic Green me ganó.

woutr_be
fuente
Gracias. funcionó, pero recorta la imagen desde arriba . (vea esto: jsfiddle.net/x86Q7 ) ¿No hay alguna forma de recortar la imagen desde el centro ?
Mahdi Ghiasi
Puede ser bastante difícil con CSS, esto es lo mejor que se me ocurrió con jsfiddle.net/D7E3E/5
woutr_be
Sí, para centrarlo correctamente, debe usar jQuery, podría ser mucho más fácil.
woutr_be
3

Esto llenará las imágenes a un tamaño específico, sin estirarlo o sin recortarlo

img{
    width:150px;  //your requirement size
    height:100px; //your requirement size

/*Scale down will take the necessary specified space that is 150px x 100px without stretching the image*/
    object-fit:scale-down;
}
Manoj Selvin
fuente
2

Para ajustar la imagen en pantalla completa, intente esto:

repetición de fondo: redondo;

suyash1798
fuente