¿Mantener la relación de aspecto con altura / ancho mínimo / máximo?

Tengo una galería en mi sitio donde los usuarios pueden subir imágenes.

Me gustaría que las imágenes se sientan en un div que mantenga su altura, las imágenes no deberían tener más de 500 píxeles de altura. El ancho debe ser automático para mantener la relación de aspecto.

HTML:

 

He probado este CSS:

 #gallery{ height: 500px; img{ max-height: 500px; max-width: 100%; } } 

Lo anterior funciona bien, la galería siempre tiene 500 px de alto y las imágenes nunca superan los 500 px de altura. Sin embargo, tengo problemas con imágenes más pequeñas, si un usuario sube una imagen realmente pequeña, me gustaría que se “explote” a un mínimo de 200 píxeles. Sé que esto se puede lograr estableciendo una min-height en la imagen, el problema con esto es que si la imagen tiene menos de 200 px de altura, por ejemplo, 2000 píxeles de ancho, la imagen se expande a 200 píxeles de alto, pero luego la la relación de aspecto está atornillada, ya que la imagen es más ancha que las imágenes div principal.

¿Cómo puedo tener una altura mínima pero mantener la relación de aspecto?

La propiedad que estás buscando es object-fit para object-fit . Esta es una de las innovaciones de Opera, puedes leer más sobre ella en su artículo de desarrollo de 2011 sobre ajuste de objetos (sí, ha durado tanto). Hace unos años, no podría hacértelo recomendar, pero caniuse muestra que todos los demás están empezando a ponerse al día:

  • Opera 10.6-12.1 (-o- prefijo)
  • Chrome 31+
  • Opera 19+
  • Safari 7.1+
  • iOS 8+
  • Android 4.4 o superior

http://caniuse.com/#search=object-fit

 #gallery img { -o-object-fit: contain; object-fit: contain; } 

Usar un valor de contain obligará a la imagen a mantener su relación de aspecto sin importar nada.

Alternativamente, es posible que desee utilizar esto en su lugar:

 #gallery img { -o-object-fit: cover; object-fit: cover; overflow: hidden; } 

http://sassmeister.com/gist/9b130efdae95bfa4338e

La única manera que conozco de lograr esto es estableciendo el width o height en auto .

 #gallery{ height: 500px; img{ max-height: 500px; width: auto; } } 

No sé si esto es posible usando solo CSS.

Sin embargo, es posible que pueda lograr lo mismo con unas pocas líneas de JavaScript:

 var img= document.querySelectorAll('img'); for(var i = 0 ; i < img.length ; i++) { img[i].onload= function() { var h= this.naturalHeight; h= Math.min(500,Math.max(200,h)); this.style.height= h+'px'; } } 

Esto establece la altura de todas las imágenes entre 200px y 500px. El ancho se escalará automáticamente.

 var img= document.querySelectorAll('img'); for(var i = 0 ; i < img.length ; i++) { img[i].onload= function() { var h= this.naturalHeight; h= Math.min(500,Math.max(200,h)); } } 
 #gallery{ height: 500px; width: 400px; overflow: hidden; } 
  

He tenido la intención de hacer algo similar, en realidad. Aquí hay algo en jQuery si te gusta eso.

SCSS:

 #gallery { height: 500px; img { max-height: 100%; } .small { width: 100%; max-width: 500px; height: auto; } .regular { width: auto; min-height: 200px; } } 

jQuery:

 $( 'img' ).each( function() { var imageWidth = parseFloat( $( this ).css( 'width' ) ); var imageHeight = parseFloat( $( this ).css( 'height' ) ); if( imageHeight <= 200 && imageWidth >= 200 ) { $( this ).addClass( 'small' ); } else { $( this ).addClass( 'regular' ); } }); 

CodePen