Сохранение пропорций с минимальной/максимальной высотой/шириной?

У меня есть галерея на моем сайте, где пользователи могут загружать изображения.

Я хотел бы, чтобы изображения сидели в div, который поддерживает его высоту, изображения должны быть не более 500 пикселей в высоту. Ширина должна быть автоматической, чтобы поддерживать соотношение сторон.

HTML:

<div id="gallery">
    <img src="uploads/my-dynamic-img.jpg">
</div>

Я пробовал этот CSS:

#gallery{
    height: 500px;

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

Это хорошо работает, галерея всегда высотой 500 пикселей, а изображения никогда не превышают 500 пикселей в высоту. Я сталкиваюсь с проблемами, хотя с меньшими изображениями, если пользователь загружает действительно маленькое изображение, я бы хотел, чтобы он "взорвался" до минимума 200 пикселей. Я знаю, что это может быть достигнуто установкой min-height на изображении, проблема с этим заключается в том, что если изображение имеет высоту менее 200 пикселей, но, скажем, ширину 2000 пикселей, изображение становится взорванным до 200 пикселей в высоту, но затем пропорция винта, поскольку изображение шире, чем родительский div изображений.

Как я могу получить минимальную высоту, но сохраняю соотношение сторон?

Ответ 1

Свойство, которое вы ищете, object-fit. Это один из нововведений Opera, вы можете больше узнать об этом в своей статье 2011 dev по объектно-ориентированной версии (да, это было так долго). Несколько лет назад я бы не смог рекомендовать его вам, но caniuse показывает, что все остальные начинают догонять:

  • Opera 10.6-12.1 (-офикс)
  • Chrome 31 +
  • Opera 19 +
  • Safari 7.1 +
  • iOS 8 +
  • Android 4.4 +

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

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

Использование значения contain заставит изображение поддерживать его соотношение сторон независимо от того, что.

В качестве альтернативы вы можете использовать это вместо:

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

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

Ответ 2

Единственный способ, которым я знаю, что возможно выполнить это, - либо установить width, либо height на auto.

#gallery{
    height: 500px;

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

Ответ 3

Я не знаю, возможно ли это, используя только CSS.

Однако вы можете выполнить одно и то же с несколькими строками 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';
  }
}

Это устанавливает высоту всех изображений в диапазоне от 200 до 500 пикселей. Ширина будет автоматически масштабироваться.

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;
}
<div id="gallery">
  <img src="http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo-med.png">

</div>

Ответ 4

Я действительно хотел сделать что-то подобное, на самом деле. Здесь что-то в jQuery, если вы в это входите.

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