Escala la imagen para ajustarla a un cuadro delimitador


¿Hay una solución solo css para escalar una imagen en un cuadro delimitador (manteniendo la relación de aspecto)? Esto funciona si la imagen es más grande que el contenedor:

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

Ejemplo:

Pero quiero escalar la imagen hasta que una dimensión sea el 100% del contenedor.

Author: sawa, 2012-04-03

13 answers

Nota: A pesar de que esta es la respuesta aceptada, la respuesta a continuación es más precisa y actualmente es compatible en todos los navegadores si tiene la opción de usar una imagen de fondo.

No, no hay una única forma de CSS de hacer esto en ambas direcciones. Se podría añadir

.fillwidth {
    min-width: 100%;
    height: auto;
}

Al elemento an para tenerlo siempre al 100% de ancho y escalar automáticamente la altura a la relación de aspecto, o el inverso:

.fillheight {
    min-height: 100%; 
    width: auto;
}

Escalar siempre a la altura máxima y ancho relativo. Para hacer ambas cosas, tendrá que determinar si la relación de aspecto es mayor o menor que su contenedor, y CSS no puede hacer esto.

La razón es que CSS no sabe cómo se ve la página. Establece reglas de antemano, pero solo después de eso es que los elementos se renderizan y sabes exactamente con qué tamaños y proporciones estás tratando. La única manera de detectarlo es con JavaScript.


Aunque usted no está buscando una solución JS Voy a añadir uno de todos modos si alguien podría necesitarlo. La forma más fácil de manejar esto con JavaScript es agregar una clase basada en la diferencia en la proporción. Si la relación ancho-alto de la caja es mayor que la de la imagen, agregue la clase "fillwidth", de lo contrario agregue la clase"fillheight".

$('div').each(function() {
  var fillClass = ($(this).height() > $(this).width()) 
    ? 'fillheight'
    : 'fillwidth';
  $(this).find('img').addClass(fillClass);
});
.fillwidth { 
  width: 100%; 
  height: auto; 
}
.fillheight { 
  height: 100%; 
  width: auto; 
}

div {
  border: 1px solid black;
  overflow: hidden;
}

.tower {
  width: 100px;
  height: 200px;
}

.trailer {
  width: 200px;
  height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tower">
  <img src="http://placekitten.com/150/150" />
</div>
<div class="trailer">
  <img src="http://placekitten.com/150/150" />
</div>
 81
Author: Stephan Muller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-07 20:20:44

Gracias a CSS3 hay una solución !

La solución es poner la imagen como background-image y luego establecer el background-size a contain.

HTML

<div class='bounding-box'>
</div>

CSS

.bounding-box {
  background-image: url(...);
  background-repeat: no-repeat;
  background-size: contain;
}

Pruébelo aquí: http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=contain

Compatibilidad total con los últimos navegadores: http://caniuse.com/background-img-opts

Para alinear el div en el centro, puede usar esto variación:

.bounding-box {
  background-image: url(...);
  background-size: contain;
  position: absolute;
  background-position: center;
  background-repeat: no-repeat;
  height: 100%;
  width: 100%;
}
 151
Author: Thomas Guillory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-19 15:02:12

Aquí hay una solución hackish que descubrí:

#image {
    max-width: 10%;
    max-height: 10%;
    transform: scale(10);
}

Esto ampliará la imagen diez veces, pero la restringirá al 10% de su tamaño final, limitándola así al contenedor.

A diferencia de la solución background-image, esto también funcionará con elementos <video>.

 32
Author: Vladimir Panteleev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-24 19:07:35

Hoy, solo di object-fit: contain. El soporte es todo menos IE: http://caniuse.com/#feat=object-fit

 18
Author: Glenn Maynard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-18 21:59:17

¿Estás buscando escalar hacia arriba pero no hacia abajo?

div {
    border: solid 1px green;
    width: 60px;
    height: 70px;
}

div img {
    width: 100%;
    height: 100%;
    min-height: 500px;
    min-width: 500px;
    outline: solid 1px red;
}

Sin embargo, esto no bloquea la relación de aspecto.

 1
Author: ericosg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-03 13:45:45

Otra solución sin imagen de fondo y sin la necesidad de un contenedor (aunque se deben conocer los tamaños máximos del cuadro delimitador):

img{
  max-height: 100px;
  max-width: 100px;
  width: auto;    /* These two are added only for clarity, */
  height: auto;   /* as the default is auto anyway */
}


Si se requiere el uso de un contenedor, entonces el ancho máximo y el alto máximo se pueden establecer en 100%:
img {
    max-height: 100%;
    max-width: 100%;
    width: auto; /* These two are added only for clarity, */
    height: auto; /* as the default is auto anyway */
}

div.container {
    width: 100px;
    height: 100px;
}

Para esto tendrías algo como:

<table>
    <tr>
        <td>Lorem</td>
        <td>Ipsum<br />dolor</td>
        <td>
            <div class="container"><img src="image5.png" /></div>
        </td>
    </tr>
</table>
 1
Author: xerxeArt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-15 09:13:45

Puede lograr esto con CSS puro, tanto para imágenes verticalmente largas como horizontalmente largas al mismo tiempo.

Aquí hay un fragmento que funciona en Chrome, Firefox y Safari (ambos usando object-fit: scale-down y sin usarlo):

figure {
  margin: 0;
}

.container {
  display: table-cell;
  vertical-align: middle;
  width: 80px;
  height: 80px;
  border: 1px solid #aaa;
}

.container_image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  margin-left: auto;
  margin-right: auto;
}

.container2_image2 {
  width: 80px;
  height: 80px;
  object-fit: scale-down;
  border: 1px solid #aaa;
}
Without `object-fit: scale-down`:

<br>
<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure class="container">
  <img class="container_image" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>

<br> Using `object-fit: scale-down`:

<br>
<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/EQgexUd.jpg">
</figure>

<br>

<figure>
  <img class="container2_image2" src="https://i.imgur.com/ptO8pGi.jpg">
</figure>
 1
Author: gabrielmaldi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-16 22:40:59

Html:

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

Css:

.container{
  width: 100px;
  height: 100px;
}


.flowerImg{
  width: 100px;
  height: 100px;
  object-fit: cover;
  /*object-fit: contain;
  object-fit: scale-down;
  object-position: -10% 0;
  object-fit: none;
  object-fit: fill;*/
}
 1
Author: Deke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-22 05:21:58

He utilizado la tabla para centrar la imagen dentro de la caja. Mantiene la relación de aspecto y escala la imagen de una manera que está totalmente dentro de la caja. Si la imagen es más pequeña que la caja, entonces se muestra como está en el centro. El siguiente código utiliza una caja de 40px de ancho y 40px de altura. (No estoy muy seguro de lo bien que funciona porque lo eliminé de otro código más complejo y lo simplifiqué un poco)

CSS:

.SmallThumbnailContainer
{
    display: inline-block; position: relative;
    float: left;    
    width: 40px;
    height: 40px;
    border: 1px solid #ccc;
    margin: 0px; padding: 0px;
}
.SmallThumbnailContainer { width: 40px; margin: 0px 10px 0px 0px; } 
.SmallThumbnailContainer tr { height: 40px; text-align: center; }
.SmallThumbnailContainer tr td { vertical-align: middle; position: relative; width: 40px;  }
.SmallThumbnailContainer tr td img { overflow: hidden; max-height: 40px; max-width: 40px; vertical-align: middle; margin: -1px -1px 1px -1px; }

HTML:

<table class="SmallThumbnailContainer" cellpadding="0" cellspacing="0">
    <tr><td>
        <img src="thumbnail.jpg" alt="alternative text"/>
    </td></tr>
    </table>
 0
Author: Antti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-23 09:20:27

Este ejemplo para estirar la imagen proporcionalmente para adaptarse a toda la ventana. Una improvisación al código correcto anterior es agregar $( window ).resize(function(){});

function stretchImg(){
    $('div').each(function() {
      ($(this).height() > $(this).find('img').height()) 
        ? $(this).find('img').removeClass('fillwidth').addClass('fillheight')
        : '';
      ($(this).width() > $(this).find('img').width()) 
        ? $(this).find('img').removeClass('fillheight').addClass('fillwidth')
        : '';
    });
}
stretchImg();

$( window ).resize(function() {
    strechImg();
});

Hay dos condiciones if. El primero sigue comprobando si la altura de la imagen es menor que el div y aplica la clase .fillheight mientras que el siguiente comprueba el ancho y aplica la clase .fillwidth. En ambos casos la otra clase se elimina usando .removeClass()

Aquí está el CSS

.fillwidth { 
   width: 100%;
   max-width: none;
   height: auto; 
}
.fillheight { 
   height: 100vh;
   max-width: none;
   width: auto; 
}

Puede reemplazar 100vh por 100% si desea estirar la imagen con en un div. Este ejemplo para estirar la imagen proporcionalmente para adaptarse a toda la ventana.

 0
Author: Mr. JCRP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-12 03:01:07

La forma más limpia y sencilla de hacer esto:

Primero algunos CSS:

div.image-wrapper {
    height: 230px; /* Suggestive number; pick your own height as desired */
    position: relative;
    overflow: hidden; /* This will do the magic */
    width: 300px; /* Pick an appropriate width as desired, unless you already use a grid, in that case use 100% */
}
img {
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    height: auto;
}

El HTML:

<div class="image-wrapper">
  <img src="yourSource.jpg">
</div>

Esto debería hacer el truco!

 0
Author: Robert Eetheart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-27 14:41:08

Esto me ayudó:

.img-class {
  width: <img width>;
  height: <img height>;
  content: url('/path/to/img.png');
}

Luego en el elemento (puede usar javascript o media queries para agregar capacidad de respuesta):

<div class='img-class' style='transform: scale(X);'></div>

Espero que esto ayude!

 0
Author: bman93,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-07 20:45:37
.boundingbox {
    width: 400px;
    height: 500px;
    border: 2px solid #F63;
}
img{
    width:400px;
    max-height: 500px;
    height:auto;
}

Estoy editando mi respuesta para explicar más mi solución ya que tengo un voto negativo.

Con los estilos establecidos como se muestra arriba en css, ahora el siguiente div html mostrará que la imagen siempre se ajusta al ancho y ajustará la relación de aspecto alta al ancho. Por lo tanto, la imagen se escalará para ajustarse a un cuadro delimitador como se preguntó en la pregunta.

<div class="boundingbox"><img src="image.jpg"/></div>
 -3
Author: zeeawan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-25 12:57:47