CSS fuerza el cambio de tamaño de la imagen y mantiene la relación de aspecto


577

Estoy trabajando con imágenes y me encontré con un problema con las relaciones de aspecto.

<img src="big_image.jpg" width="900" height="600" alt="" />

Como puede ver, heighty widthya están especificados. Agregué la regla CSS para las imágenes:

img {
  max-width:500px;
}

Pero para big_image.jpg, recibo width=500y height=600. Cómo puedo configurar las imágenes para cambiar su tamaño, manteniendo sus relaciones de aspecto.

Respuestas:


775

img {
  display: block;
  max-width:230px;
  max-height:95px;
  width: auto;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="http://i.stack.imgur.com/aEEkn.png">

Esto hará que la imagen se reduzca si es demasiado grande para el área especificada (como inconveniente, no agrandará la imagen).


11
¿Existe una versión de esto que agrandará las imágenes para que se ajusten también a su contenedor? Intenté max-width / max-height como números con width / height como auto, pero como setec dijo anteriormente, no agrandará la imagen. He intentado usar min-width / min-height también. Simplemente no puedo hacer la combinación correcta. Simplemente quiero que cualquier imagen que tenga que poner en este contenedor, se muestre en su tamaño máximo posible sin cambiar la relación de aspecto, independientemente de si eso implica reducir o hacer crecer la imagen para lograrlo.
Dee2000

77
Parece que se muestra: el bloque ya no es necesario.
actimel

3
Tenga en cuenta que la pregunta se refería a una <img>que en sí misma incluye un ancho y un alto, y creo que eso significa que debe usar !importantpara evitar la información de ancho / alto de la etiqueta.
Alexis Wilke

18
Las reglas de @AlexisWilke CSS anulan los atributos html. !importantno es necesario.
Jargs

55
Usarlo en Chrome, no funciona para mí, incluso con! Important
Ray

266

He luchado bastante con este problema, y ​​finalmente llegué a esta solución simple:

object-fit: cover;
width: 100%;
height: 250px;

Puede ajustar el ancho y la altura para satisfacer sus necesidades, y la propiedad de ajuste de objetos hará el recorte por usted.

Salud.


44
object-fites fantástico, un gran consejo! Hay algunas buenas bibliotecas de polyfill si alguien se pregunta acerca de la compatibilidad con IE.
suavemente

77
Encantador, ten en cuenta que esto no funciona para IE, sin embargo
Guival

1
No es viable en SAMSUNG Signage Display WebApps.
Marzo

3
La mejor solución disponible
Cynthia Sanchez

10
¡También puede usar object-fit: containy especificar un ancho o alto!
Broper

236

Las soluciones a continuación permitirán ampliar y reducir la imagen , dependiendo del ancho del cuadro principal.

Todas las imágenes tienen un contenedor principal con un ancho fijo solo con fines de demostración . En producción, este será el ancho de la caja principal.

Mejores prácticas (2018):

Esta solución le dice al navegador que renderice la imagen con el ancho máximo disponible y ajuste la altura como un porcentaje de ese ancho.

.parent {
  width: 100px;
}

img {
  display: block;
  width: 100%;
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<div class="parent">
  <img width="400" height="400" src="https://placehold.it/400x400">
</div>

Solución más elegante:

Con la solución más elegante, podrá recortar la imagen independientemente de su tamaño y agregar un color de fondo para compensar el recorte.

.parent {
  width: 100px;
}

.container {
  display: block;
  width: 100%;
  height: auto;
  position: relative;
  overflow: hidden;
  padding: 34.37% 0 0 0; /* 34.37% = 100 / (w / h) = 100 / (640 / 220) */
}

.container img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<p>This image is originally 640x220, but should get resized by the CSS:</p>
<div class="parent">
  <div class="container">
    <img width="640" height="220" src="https://placehold.it/640x220">
  </div>
</div>

Para la línea que especifica el relleno, debe calcular la relación de aspecto de la imagen, por ejemplo:

640px (w) = 100%
220px (h) = ?

640/220 = 2.909
100/2.909 = 34.37%

Entonces, el relleno superior = 34.37%.


1
Funciona, pero debe tener un ancho máximo: 100% en lugar del ancho en la mayoría de los usos.
Dudeista

No creo que !importantsea ​​necesario aquí.
Flimm

1
Con el padre configurado en 100px. ¿Cómo funcionará esto de manera receptiva?
Remi

@Remi es para fines de demostración. He agregado una aclaración al principio de la respuesta.
Aternus

@Flimm se usó anteriormente por problemas de compatibilidad, en 2016 ya no es necesario.
Aternus

64

La propiedad de tamaño de fondo es, por ejemplo,> = 9 solamente, pero si eso está bien con usted, puede usar un div con background-imagey establecer background-size: contain:

div.image{
    background-image: url("your/url/here");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

Ahora puede establecer el tamaño de su div en lo que desee y no solo la imagen mantendrá su relación de aspecto, sino que también se centralizará vertical y horizontalmente dentro del div. Simplemente no olvide establecer los tamaños en el CSS ya que los divs no tienen el atributo ancho / alto en la etiqueta.

Este enfoque es diferente a la respuesta de setecs, usando esto el área de la imagen será constante y definida por usted (dejando espacios vacíos, ya sea horizontal o verticalmente, dependiendo del tamaño div y la relación de aspecto de la imagen), mientras que la respuesta de setecs le dará un cuadro que exactamente tamaño de la imagen a escala (sin espacios vacíos).

Editar: de acuerdo con la documentación de tamaño de fondo de MDN , puede simular la propiedad de tamaño de fondo en IE8 utilizando una declaración de filtro patentada:

Aunque Internet Explorer 8 no admite la propiedad de tamaño de fondo, es posible emular algunas de sus funciones utilizando la función no estándar -ms-filter:

-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='path_relative_to_the_HTML_file', sizingMethod='scale')";

2
finalmente una solución CSS única para maximizar una imagen manteniendo su relación de aspecto, gracias. Suerte que IE antes de 9 es cada vez menos importante.
humanityANDpeace

2
Gran solución, gracias! También tenga en cuenta que puede reemplazar 'contener' por 'cubrir' si desea llenar el div por completo y recortar píxeles adicionales que no se ajustan a la proporción
mbritto

Esta debería ser la respuesta correcta. Amo esta solución Mantiene tus proporciones y es fácil de entender.
skolind

1
Si bien esta es una respuesta correcta programáticamente, si una imagen "importa" de esta manera, no tiene atributos img, por lo que está matando al SEO.
fat_mike

¡Excelente! Fue la única de estas soluciones que funcionó tanto para las imágenes verticales y horizontales como para los contenedores verticales y horizontales de la imagen (por ejemplo, dependiendo del tamaño de la ventana) en las 4 combinaciones y, adicionalmente, también en IE11, que parecía ser bastante un requerimiento. ¡Gracias!
cupiqi09

53

Muy similar a algunas respuestas aquí, pero en mi caso tenía imágenes que a veces eran más altas, a veces más grandes.

Este estilo funcionó de maravilla para asegurarse de que todas las imágenes usen todo el espacio disponible, mantengan la proporción y no los cortes:

.img {
   object-fit: contain;
   max-width: 100%;
   max-height: 100%;
   width: auto;
   height: auto;
}

object-fitfunciona para mí ¿funciona en todos los navegadores?
Murtuza Zabuawala

¿Hay .imguna clase sobre el padre o la imagen? ¿Podría hacer un jsfiddle con ejemplo para imágenes de retrato y paisaje?
Diseño de Adrian

19

Elimine la propiedad "altura".

<img src="big_image.jpg" width="900" alt=""/>

Al especificar ambos, está cambiando la relación de aspecto de la imagen. Solo configurando uno cambiará el tamaño pero conservará la relación de aspecto.

Opcionalmente, para restringir sobredimensionamientos:

<img src="big_image.jpg" width="900" alt="" style="max-width:500px; height:auto; max-height:600px;"/>

no puedo hacerlo con todas las imágenes, ya hay muchas imágenes colocadas en muchos archivos html
moonvader

2
Okay. pruebe img {max-width: 500px; altura: auto; max-height: 600px;}
el Dude

1
Se debe agregar información útil como ese comentario a su publicación. De esa manera, podemos ver de inmediato lo que se te ocurrió.
Bram Vanroy

2
La desventaja de omitir el heightatributo en la imgetiqueta es que el navegador no puede calcular cuánto espacio ocupará la imagen antes de descargar la imagen. Esto hace que la página sea más lenta y puede generar más "saltos".
Flimm

11

Simplemente agregue esto a su CSS, se reducirá y expandirá automáticamente manteniendo la proporción original.

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

2
Esta es la misma respuesta que la respuesta de setec , excepto que se usa en 100%lugar de un valor de píxel específico.
Flimm

55
display: block;es innecesario
Flimm

Eso es perfecto y funciona con imágenes de cualquier tamaño y proporción
Le Droid

8

No hay una forma estándar de preservar la relación de aspecto para imágenes con width, heighty max-widthespecificadas juntas.

Por lo tanto, nos vemos obligados a especificar widthy heightevitar "saltos" en la página durante la carga de imágenes, o para usar max-widthy no especificar dimensiones para las imágenes.

Especificar solo width(sin height) generalmente no tiene mucho sentido, pero puede intentar anular el heightatributo HTML agregando una regla comoIMG {height: auto; } en su hoja de estilo.

Ver también el error relacionado con Firefox 392261 .


gracias, funciona en versiones modernas de IE, Opera, FF y Chrome. Necesito algo de tiempo para probarlo con otros navegadores.
moonvader

77
No lo use !importanten CSS. Es un truco que eventualmente regresará para atormentarte.
Automático

1
Ni siquiera necesitas !importantaquí.
Flimm

8

Aquí hay una solución:

img {
   width: 100%;
   height: auto;
   object-fit: cover;
}

Esto asegurará que la imagen siempre cubra a todo el padre (escalando hacia arriba y hacia abajo) y mantenga la misma relación de aspecto.


5

Establezca la clase CSS de su etiqueta de contenedor de imagen en image-class:

<div class="image-full"></div>

y agrega esto a tu hoja de estilo CSS.

.image-full {
    background: url(...some image...) no-repeat;
    background-size: cover;
    background-position: center center;
}

5

Para mantener una imagen receptiva y al mismo tiempo hacer que la imagen tenga una determinada relación de aspecto, puede hacer lo siguiente:

HTML:

<div class="ratio2-1">
   <img src="../image.png" alt="image">
</div>

Y SCSS:

.ratio2-1 {
  overflow: hidden;
  position: relative;

  &:before {
    content: '';
    display: block;
    padding-top: 50%; // ratio 2:1
  }

  img {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
  }
}

Esto se puede utilizar para aplicar una determinada relación de aspecto, independientemente del tamaño de la imagen que carguen los autores.

Gracias a @Kseso en http://codepen.io/Kseso/pen/bfdhg . Consulte esta URL para obtener más proporciones y un ejemplo de trabajo.


Me gusta esto ya que funciona con círculos / border-radius. Pero desafortunadamente, recorta la imagen y no lo hace tan bien al hacer un borde para la imagen en el div por lo que he intentado.
Jake

4

Para forzar una imagen que se ajuste a un tamaño exacto, no necesita escribir demasiados códigos. Es tan simple

img{
    width: 200px;
    height: auto;
    object-fit: contain; /* Fit logo in the image size */
        -o-object-fit: contain; /* Fit logo fro opera browser */
    object-position: top; /* Set logo position */
        -o-object-position: top; /* Logo position for opera browser */
    }
<img src="http://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png" alt="Logo">


4

https://jsfiddle.net/sot2qgj6/3/

Aquí está la respuesta si desea poner una imagen con un porcentaje fijo de ancho , pero no píxeles fijos de ancho .

Y esto será útil cuando se trata de diferentes tamaños de pantalla .

Los trucos son

  1. Utilizando padding-toppara establecer la altura desde el ancho.
  2. Utilizando position: absolutepara poner la imagen en el espacio de relleno.
  3. Utilizando max-height and max-widthpara asegurarse de que la imagen no superará el elemento principal.
  4. usando display:block and margin: autopara centrar la imagen.

También he comentado la mayoría de los trucos dentro del violín.


También encuentro otras formas de hacer que esto suceda. No habrá una imagen real en html, por lo que personalmente busco la respuesta principal cuando necesito el elemento "img" en html.

CSS simple utilizando el fondo http://jsfiddle.net/4660s79h/2/

imagen de fondo con la palabra en la parte superior http://jsfiddle.net/4660s79h/1/

El concepto para utilizar la posición absoluta es de aquí http://www.w3schools.com/howto/howto_css_aspect_ratio.asp


Esto no funciona si "la altura y el ancho ya están especificados" como menciona la pregunta original. Hay momentos en que desea forzar el ancho y la altura y luego ampliar / reducir la imagen de acuerdo con la relación de aspecto.
Diseño de Adrian

3

Puedes usar esto:

img { 
    width: 500px; 
    height: 600px; 
    object-fit: contain; 
    position: relative; 
    top: 50%; 
    transform: translateY(-50%); 
}

2

Puedes crear un div como este:

<div class="image" style="background-image:url('/to/your/image')"></div>

Y usa este CSS para darle estilo:

height: 100%;
width: 100%;
background-position: center center;
background-repeat: no-repeat;
background-size: contain; // this can also be cover

Esto estirará el div al 100% del ancho de su padre, pero no mantendrá la relación de aspecto de la imagen.
David Ball

¿Lo intentaste? Lo tengo funcionando jsfiddle.net/zuysj22w . ¿Puedes mostrar tu caso? @DavidBall
Chun Yang

Esta es una solución similar a la respuesta de Hoffmann .
Flimm

2

Sugeriría un enfoque receptivo, la mejor práctica sería usar las unidades de Viewport y los atributos min / max de la siguiente manera:

img{
  display: block;
  width: 12vw;
  height:12vw;
  max-width:100%;
  min-width:100px;
  min-height:100px;
  object-fit:contain;
}

1

Esto hará que la imagen se reduzca si es demasiado grande para el área especificada (como inconveniente, no agrandará la imagen).

La solución de setec está bien para "Shrink to Fit" en modo automático. Pero, para EXPANDIR de manera óptima para que se ajuste al modo 'automático', primero debe colocar la imagen recibida en una identificación temporal. Compruebe si se puede expandir en altura o en ancho (dependiendo de su relación de aspecto v / s la relación de aspecto de su bloque de pantalla),

$(".temp_image").attr("src","str.jpg" ).load(function() { 
    // callback to get actual size of received image 

    // define to expand image in Height 
    if(($(".temp_image").height() / $(".temp_image").width()) > display_aspect_ratio ) {
        $(".image").css('height', max_height_of_box);
        $(".image").css('width',' auto');
    } else { 
        // define to expand image in Width
        $(".image").css('width' ,max_width_of_box);
        $(".image").css('height','auto');
    }
    //Finally put the image to Completely Fill the display area while maintaining aspect ratio.
    $(".image").attr("src","str.jpg");
});

Este enfoque es útil cuando las imágenes recibidas son más pequeñas que el cuadro de visualización. Debe guardarlos en su servidor en tamaño original pequeño en lugar de su versión ampliada para llenar su caja de visualización más grande para ahorrar en tamaño y ancho de banda.


Aunque la publicación de la pregunta no lo deletreó, creo que OP implicaba firmemente que estaba buscando una solución solo para CSS.
Flimm

0

img {
  max-width: 80px; /* Also works with percentage value like 100% */
  height: auto;
}
<p>This image is originally 400x400 pixels, but should get resized by the CSS:</p>
<img width="400" height="400" src="https://i.stack.imgur.com/aEEkn.png">

<p>Let's say the author of the HTML deliberately wants
  the height to be half the value of the width,
  this CSS will ignore the HTML author's wishes, which may or may not be what you want:
</p>
<img width="400" height="200" src="https://i.stack.imgur.com/aEEkn.png">


0

¿Qué tal usar un pseudo elemento para la alineación vertical? Este código menos es para un carrusel, pero supongo que funciona en todos los contenedores de tamaño fijo. Mantendrá la relación de aspecto e insertará @ barras gris oscuro en la parte superior / inferior o izquierda / escritura para la dimensión más corta. Mientras tanto, la imagen está centrada horizontalmente por la alineación de texto y verticalmente por el pseudo elemento.

    > li {
      float: left;
      overflow: hidden;
      background-color: @gray-dark;
      text-align: center;

      > a img,
      > img {
        display: inline-block;
        max-height: 100%;
        max-width: 100%;
        width: auto;
        height: auto;
        margin: auto;
        text-align: center;
      }

      // Add pseudo element for vertical alignment of inline (img)
      &:before {
        content: "";
        height: 100%;
        display: inline-block;
        vertical-align: middle;
      }
    }

0

Presentación a pantalla completa:

img[data-attribute] {height: 100vh;}

Tenga en cuenta que si la altura del puerto de vista es mayor que la imagen, la imagen se degradará naturalmente en relación con la diferencia.


-1

Creo, finalmente, que esta es la mejor solución, fácil y simple :

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

1
¿Podría explicar brevemente por qué ayuda esta solución? (Solo una oración es suficiente.)
Aenadon

Simplemente porque la imagen mantendrá la relación de aspecto, mientras que el ancho máximo y la altura máxima evitarán que sea más grande que el contenedor
Uknow
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.