Raphael Jeger
Raphael Jeger

Reputation: 5232

Fill div with cropped image, preserve aspect ratio

I have DIVs on my page containing IMGs. On image-click, they get opened in a lightbox, but inside the DIV, they should fill the DIV completely, but preserve aspect ratio.

This is what I achieved so far, problem is that aspect ratio is not preserved when image is in portrait-mode.

http://jsfiddle.net/btvET/1/

So what I need is a CSS-method to center the images vertically and horizontally while filling the wrapping DIV completely (and of course cropping the overflowing parts of the image).

Is this possible, CSS only, or is JS required? Browser-compatibility is IE8 and higer and all modern browsers.

Solved it like this with JS/JQuery:

function resizeImages(){
    $("#container img").each(function() {
        var thisHeight = $(this).height();
        var thisWidth = $(this).width();
        var containerWidth = $(this).parent().width();
        var containerHeight = $(this).parent().height();
        var diff = 0;
        if(thisHeight > thisWidth){
            //portrait
            $(this).css("width","100%");
            thisHeight = $(this).height();
            diff = thisHeight - containerHeight;
            $(this).css("margin-top",-(diff/2));
        }
        else if(thisWidth > thisHeight){
            //landscape
            $(this).css("height","100%");
            var thisWidth = $(this).width();
            if(thisWidth < containerWidth){
                $(this).css("width", containerWidth);
                thisWidth = containerWidth;
            }
            diff = thisWidth - containerWidth;
            $(this).css("margin-left",-(diff/2));
        }
        $(this).css("opacity",1);
    });
}

The set-opacity to 1 at the end is because I only want to show the images when finished resizing, so I set them to opacity:0 in CSS and then after resizing show them.

This works for me in all container widths and image modes.

Upvotes: 0

Views: 2360

Answers (2)

realh
realh

Reputation: 1131

This sounds similar to something I wanted to do, and I think I've managed to achieve it without Javascript, but it needs a dummy blank image. I have an image that's 1920x1537 and I want to display it elsewhere clipped to a 16:9 aspect ratio, but responsive. First I created a blank 1920x720 image. I used GIF because its file size (2.1KB) was considerably less than PNG or JPEG in this case.

HTML:

<div class="responsive-clipped mainphoto-margins">
    <img class="img-responsive" src="imgs/blank16x9.gif">
    <img class="img-responsive img-clipped" src="imgs/main9.jpg">
</div>

CSS:

.responsive-clipped {
    position: relative;
    left: 0;
    top: 0;
    width: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

.img-clipped {
    position: absolute;
    left: 0;
    top: -60%;
}

/* From Bootstrap */
.img-responsive {
    display: block;
    max-width: 100%;
    height: auto;
}

I played with the top: -60% setting until it looked right for this image. I'm not sure whether you could achieve vertical centering with 50% or if you'd have to calculate it based on the aspect ratio. In the latter case, if each image has a different aspect ratio you'd probably best stick with the Javascript solution.

Upvotes: 0

Lucas Veiga
Lucas Veiga

Reputation: 1795

This will require an Javascript implementation. With jQuery, you can check if height is larger than width and vice versa.

You can do this:

$(".container img").each(function(){
var thisWidth = $(this).width();
var thisHeight = $(this).height();

if(thisWidth > thisHeight) {
    $(this).css("width", "auto");
    $(this).css("height", "100%");
} else if(thisHeight > thisWidth) {
     $(this).css("width", "100%");
     $(this).css("height", "auto");
}

});

Hope this helps.

Upvotes: 2

Related Questions