7

Image in a container div, with the height issue

So i have a gallery where most my images are currently controlled 100% by CSS. However, in setting min-height: 100%; on my images, i cause some to stretch. I don't have too many problematic photos, but it's out of my control what the user will upload.

Is there anyway with jQuery i can get image height and check if it's meeting a requirement, and if not, somehow increase the image width in order to meet the height requirement but keep things all in ratio? So i therefore avoid causing any distortion but keep the gallery neat by having divs without gaps.

Note: The image provided is what happens when i remove my min-height: 100%; so that you can see my issue.

Update - - - - -

I found a solution that seems to work ok for the moment, it might not be the best attempt but i found another answer that helped me: How to resize images proportionally / keeping the aspect ratio?

I simply tweaked the code ever so slightly, now if an image doesn't meet the minHeight required it will resize the image in proportion so until the minHeight is then reached. Seems work fine for me in testing.

**Update Final ********* After playing around i took a small snippit from the thumb script, just the part where it absolutely positions the images within the container.

$(window).load(function() {

    $('.thumbnail img').each(function() {
        var maxWidth = 320; // Max width for the image
        var minHeight = 270;    // Max height for the image
        var ratio = 0;  // Used for aspect ratio
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        if(width > maxWidth){
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio);  // Scale height based on ratio
            height = height * ratio;    // Reset height to match scaled image
            width = width * ratio;    // Reset width to match scaled image
        }

        // Check if current height is larger than max
        if(height < minHeight){
            ratio = minHeight / height; // get ratio for scaling image
            $(this).css("height", minHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
            width = width * ratio;    // Reset width to match scaled image
        }

        var $img = $(this),
        css = {
            position: 'absolute',
            marginLeft: '-' + ( parseInt( $img.css('width') ) / 2 ) + 'px',
            left: '50%',
            top: '50%',
            marginTop: '-' + ( parseInt( $img.css('height') ) / 2 ) + 'px'
        };

        $img.css( css );
   });

});

This loops through all my thumbnails, resizes them accordingly. So if the minimum height is not met, the image will be scaled up until the height fits my thumbnail container. Then the bottom part will take take each image, absolutely position it, and take the width and height and divide by 2, in order to work out how much to minus off on the margins to center the image. I'm still tweaking this, but seems to work well for me at the moment. I hope this helps someone else.

Alternatively

Anyone with a similar issue i found this: http://joanpiedra.com/jquery/thumbs/ I had begun writing my own to do exactly this, but im going to look into how well this works and adapt it as needed.

Community
  • 1
  • 1
Gerico
  • 5,079
  • 14
  • 44
  • 85
  • [Get image size with JavaScript](http://stackoverflow.com/questions/623172/how-to-get-image-size-height-width-using-javascript) – Eich Mar 11 '13 at 13:36
  • You might get some help from this, http://stackoverflow.com/questions/1682495/jquery-resize-to-aspect-ratio?rq=1 – Nazmul Mar 11 '13 at 13:58

4 Answers4

5

I found a solution that seems to work ok for the moment, it might not be the best attempt but i found another answer that helped me: How to resize images proportionally / keeping the aspect ratio?

Updated question with my findings

$(window).load(function() {
    $('.image-gallery-item-image-link img').each(function() {
        var maxWidth = 320; // Max width for the image
        var minHeight = 270;    // Max height for the image
        var ratio = 0;  // Used for aspect ratio
        var width = $(this).width();    // Current image width
        var height = $(this).height();  // Current image height

        if(width > maxWidth){
            ratio = maxWidth / width;   // get ratio for scaling image
            $(this).css("width", maxWidth); // Set new width
            $(this).css("height", height * ratio);  // Scale height based on ratio
            height = height * ratio;    // Reset height to match scaled image
            width = width * ratio;    // Reset width to match scaled image
        }

        // Check if current height is larger than max
        if(height < minHeight){
            ratio = minHeight / height; // get ratio for scaling image
            $(this).css("height", minHeight);   // Set new height
            $(this).css("width", width * ratio);    // Scale width based on ratio
            width = width * ratio;    // Reset width to match scaled image
        }

        var $img = $(this),
        css = {
            position: 'absolute',
            marginLeft: '-' + ( parseInt( $img.css('width') ) / 2 ) + 'px',
            left: '50%',
            top: '50%',
            marginTop: '-' + ( parseInt( $img.css('height') ) / 2 ) + 'px'
        };

        $img.css( css );
   });
});
Community
  • 1
  • 1
Gerico
  • 5,079
  • 14
  • 44
  • 85
3

well, if keeping the entire picture visible isn't necessary(e.g. thumbnails in a gallery), you could accomplish this with css only. it seems you have landscape type photos. html

<div class="img-container">
<img src="path/to/img.png" alt="">
</div>

css:

div > img {
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
width:100%;
height:100%;

}

jquery:
$(document).ready(function(){
     $(".imgcontainer > img").each(function(){
       var thisimg = "url("+$(this).attr('src')+")";
       $(this).css({'background-image': thisimg });
       $(this).attr('src', '');
     });

}); 
Todd
  • 5,314
  • 3
  • 28
  • 45
  • The problem i see with this is that setting a background on an img doesn't work, unless i am reading it wrongly. I want to be setting the img as a background image on the div, no? – Gerico Mar 12 '13 at 10:43
  • Hey, man. It should be working. Works like a charm for me. I tested on js fiddle, as i didn't test at all for my initial post. [HERES THE JS FIDDLE](http://jsfiddle.net/tpressley1/X728b/3/). Hope this helps!!! – Todd Mar 13 '13 at 04:35
  • Ah, it would seem in my firefox, the image is not displaying. I checked in chrome and i can see the image :S – Gerico Mar 13 '13 at 09:01
  • Matt, did you find my answer helpful? hint hint. LOL. – Todd Mar 13 '13 at 19:56
1

Whose aspect ratio you are talking about ? aspect ratio of your gallery or the aspect ratio of the image ? You can't keep an image in correct aspect ratio by changing one dimension only (here height). In order to keep aspect ratio, you must change both the height and width of the image. Any way if you want try this :

var img = document.getElementById('imageid'); 
var width = img.clientWidth;
var height = img.clientHeight;
if(width >height)
    $(img).attr('style',"width=100%");
else
    $(img).attr('style',"height=100%");

What I am trying to do is that, set the css of the largest dimension to 100%. It'll do the trick.

codeVerine
  • 742
  • 3
  • 14
0

So, I realize this question asked a while ago. But I've since found a sweet css only way to maintain the aspect ratio of an element, fluidly. Try it out:

#targetElement {
    max-width: 100%;
}

#targetElement:after {
    content: '';
    width: 100%;
    padding-bottom: <aspect-ratio>%; // where (height / width)*100 = <aspect-ratio>
}

Yeah, so I use this trick all the time now, and it's definitely more performant and less verbose than using javascript, or even less efficient, JQuery. Hope this helps somebody somewhere! If you're a LESS person, I have a mixin Gist on Github that does this -- that's how often I use it! It lives here: Sweet AR trick.

Todd
  • 5,314
  • 3
  • 28
  • 45