4

I'm trying to fit any sized image inside a (always) square div, and retain the aspect when the size of the parent div changes. Here's what I'm doing:

CSS:

.photo_container {
    width: 250px;
    height: 250px;
    overflow: hidden;
    border-style: solid;
    border-color: green;
    float:left;
    margin-right:10px;
    position: relative;
}

.photo_container a img{
    position:absolute;
}

HTML

<!--p>Photo's height>width </p-->
<div class="photo_container">
    <a href="#">
        <img class="photo"  src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/ECurtis.jpg/224px-ECurtis.jpg" 
style="width:100%; height:auto;">
        </img>
    </a>
</div>

<!--p>Photo's width>height </p-->
<div class="photo_container">
    <a href="#">
        <img class="photo"  src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Altja_j%C3%B5gi_Lahemaal.jpg/220px-Altja_j%C3%B5gi_Lahemaal.jpg" 
style="width:auto; height:100%;left=-100px">
        </img>
    </a>
</div>

Javascript:

// fix image size on load
$(".photo").one("load", function() {
  fixImage($(this));
}).each(function() {
  if(this.complete) $(this).load();
});

// Just to test if everything's working fine
$(".photo").on("click",function(){
   var rand = Math.floor(Math.random() * 200) + 80;  
    $(this).parent().parent().width(rand);
    $(this).parent().parent().height(rand);   
   fixImage($(this));
});

// Brings the photo dead center
function fixImage(obj){
        //alert("something changed");
        var pw = obj.parent().parent().width(); 
        var ph = obj.parent().parent().height();         
        var w = obj.width();
        var h = obj.height();
        console.log(w+"   "+pw);
        if(h>w){
            var top = (h-ph)/2;
            obj.css("top",top*-1);
        }else{
            var left = (w-pw)/2;
            obj.css("left",left*-1);            
        }

}

Working example: http://jsfiddle.net/vL95x81o/4

How can this be done without using jquery but only CSS? If the size of the div never changes, this solution is fine. But I'm looking into responsive designs and seems like the size of the photo_container div might need to change (via CSS) based on the size of the screen.

Here are the photos before being cropped:

Portrait Image Landscape Image

3
  • 1
    Can you use a background image of a div rather than a img tag?? Commented Sep 24, 2015 at 15:48
  • As I mentioned below, I rather not as it would mean some change in the code which is dependent on having <a> and <img>. Also not sure yet if this will affect SEO, how Googlebot picks up the images. Commented Sep 24, 2015 at 16:07
  • Some other good answers here: stackoverflow.com/questions/10830735/… Commented Sep 24, 2015 at 17:21

4 Answers 4

2

You could do something like this:

http://jsfiddle.net/vL95x81o/5/

<!--p>Photo's height>width </p-->
<div class="photo_container">
    <div class="photo photo--1">
    </div>
</div>

<!--p>Photo's width>height </p-->
<div class="photo_container">
    <div class="photo photo--2">
    </div>
</div>

.photo_container {
    width: 250px;
    height: 250px;
    overflow: hidden;
    border-style: solid;
    border-color: green;
    float:left;
    margin-right:10px;
    position: relative;
}

.photo {
    height: 100%;
    width: 100%;
}

.photo--1 {
    background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/ECurtis.jpg/224px-ECurtis.jpg') no-repeat center center;
    background-size: cover;
}

.photo--2 {
      background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Altja_j%C3%B5gi_Lahemaal.jpg/220px-Altja_j%C3%B5gi_Lahemaal.jpg') no-repeat center center;
    background-size: cover;
}

I have changed the imgs to divs with background images and used background position cover with the image being centered.

Sign up to request clarification or add additional context in comments.

1 Comment

Is it not possible without bringing in background image? Sort of don't want to change the current structure (including <a>) as I have some other JS dependent on it. Also will this have any affect on SEO? Like how the images are picked up by Googlebot..
1

The background solution that others have posted was my initial thought, but if you want to still use images then you could do the following:

CSS:

.photo_container {
    width: 250px;
    height: 250px;
    overflow: hidden;
    border-style: solid;
    border-color: green;
    float:left;
    margin-right:10px;
    position: relative;
}

.photo_container img {
    min-width: 100%;
    min-height: 100%;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translateY(-50%) translateX(-50%);
}

HTML:

<div class="photo_container">
    <a href="#">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/ECurtis.jpg/224px-ECurtis.jpg" />
    </a>
</div>

<div class="photo_container">
    <a href="#">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Altja_j%C3%B5gi_Lahemaal.jpg/220px-Altja_j%C3%B5gi_Lahemaal.jpg" />
    </a>
</div>

This will make any image inside to be either 100% high or 100% wide, depending on the shortest attribute, and centralise them horizontally and vertically.

Edit

It's worth noting that transform is not supported in IE8 or Opera Mini - http://caniuse.com/#feat=transforms2d

4 Comments

Cool! This is close to what I wanted - no change in the current structure. But I'm seeing a gap of 1pix randomly appear between the image and the border on the left for portrait, and on the top for landscape. Any idea why this happens?
I see what you mean actually, but only if the height or width of the div is an odd number - like 251px? A little hack for this would be to set min-width: 101%; and min-height: 101%; so there is always a slight overlap, but I'll have a look later to see if I can find a way to stop this happening with 100%.
Thanks for the solution, it works like a charm. Want to mention that even background image is not supported in IE8 and only partially in Opera Mini. So for those i'll resort back to jquery.
Great, I'm pleased it is suitable for you. I haven't been able to look into this again yet but if I have any more information once I have I'll add it back here for you
0

Use background images.

.photo_container {
    width: 250px;
    height: 250px;
    overflow: hidden;
    border-style: solid;
    border-color: green;
    float:left;
    margin-right:10px;
    position: relative;
}
.photo_container a{
   
  /* Set the background size to cover to scale the image */
  background-size: cover;

  /* Position the image in the center */
  background-position: 50% 50%;

  background-repeat: no-repeat;

    position:absolute;
  width: 100%;
  height: 100%;
}
<!--p>Photo's height>width </p-->
<div class="photo_container">
    <a href="#"  style="background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/ECurtis.jpg/224px-ECurtis.jpg);">
    </a>
</div>

<!--p>Photo's width>height </p-->
<div class="photo_container" >
    <a href="#" style="background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Altja_j%C3%B5gi_Lahemaal.jpg/220px-Altja_j%C3%B5gi_Lahemaal.jpg);">
    </a>
</div>

Comments

0

I solved this without using background-images or JS. The height comes from the before tag in the container. The 100% of the padding equals 100% of the widht. So the height has always the same width.

http://jsfiddle.net/a1rLeq06/

 <!--p>Photo's height>width </p-->
<div class="photo_container">
    <a href="#">
        <img class="photo"  src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/57/ECurtis.jpg/224px-ECurtis.jpg" 
style="width:100%; height:auto;">
        </img>
    </a>
</div>

<!--p>Photo's width>height </p-->
<div class="photo_container">
    <a href="#">
        <img class="photo"  src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Altja_j%C3%B5gi_Lahemaal.jpg/220px-Altja_j%C3%B5gi_Lahemaal.jpg" 
style="width:auto; height:100%;left=-100px">
        </img>
    </a>
</div>

The css:

.photo_container {
    width: 20%;
    display: inline-block;
    overflow: hidden;
    position: relative;
    margin: 10px 0;
}

.photo_container:before {
    content: '';
    display: block;
    padding-top: 100%;
}

.photo {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.