Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: Fit image by its smaller side

Tags:

html

css

I'm trying to create an icon container that will display any image size (long or wide).

The image should fit the container with its smaller side, while extras will be outside the container. Before applying overflow: hidden it should work like this.

enter image description here

Its seems fairly easy to do with js, but I'm curious to find a css solution.

<div class="container">
   <img src="test.png"/>
</div>

.container {
   width: 30px;
   height: 30px;
}
.container img {
   position: relative;
   left: 50%;
   top: 50%;
   transform: translateY(-50%) translateX(-50%);
}
like image 567
skyisred Avatar asked Feb 27 '15 05:02

skyisred


2 Answers

https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit

turns out there's another way to do this.

<img style='height: 100%, width: 100%, object-fit: cover'/> 

will do the work. It's CSS3 stuff.

Fiddle: http://jsfiddle.net/mbHB4/3/

like image 169
Shih-Min Lee Avatar answered Oct 13 '22 20:10

Shih-Min Lee


This is a rather challenging task if you don't want to resort to CSS backgrounds with background-size:cover (though that really isn't a bad solution either) because of one key factor: landscape vs portrait images. There's no way to detect the orientation of an image in CSS. This is a problem because you can't just assign height and width (or max-height and max-width) to 100% and expect it to work. It will distort the image and lose the aspect ratio. I suggest in this case to use some amount of javascript to differentiate the two. It's unfortunate, but necessary if you want to achieve this effect with HTML img elements (again, not the only solution. Background images are still viable).

Here's what I came up with to achieve this effect:

var images = document.querySelectorAll('.container img');
for(var i = 0, len = images.length; i < len; i++) {
  images[i].addEventListener('load', function() { 
    this.className += (this.width > this.height) ? ' landscape' : ' portrait';
  });
}
.container {
    position: relative;
    width: 50px;
    height: 50px;
    margin: 3em auto;
}
.container:after {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    border: 2px solid;
    box-sizing: border-box;
}
.container img {
    position: absolute;
    max-width: 100%;
    max-height: 100%;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 2px;
    box-sizing: border-box;
}

.container img.landscape {
    max-width: none;
}
.container img.portrait {
    max-height: none;
}
<div class="container">
    <img src="//placehold.it/200x300"/>
</div>

<div class="container">
    <img src="//placehold.it/300x200"/>
</div>

<div class="container">
    <img src="//placehold.it/200x200"/>
</div>

<div class="container">
    <img src="//placehold.it/500x100"/>
</div>
like image 24
Joseph Marikle Avatar answered Oct 13 '22 19:10

Joseph Marikle