CSS scale and square center crop image

53,304

Solution 1

You can do this easily in CSS if you use background-image.

.thumb {
    display: inline-block;
    width: 200px;
    height: 200px;
    margin: 5px;
    border: 3px solid #c99;
    background-position: center center;
    background-size: cover;
}

In this fiddle, first image is 400x800, second image is 800x400:

http://jsfiddle.net/samliew/tx7sf

Solution 2

Updated to handle cases where image width is greater than height.

You can do this with pure CSS. Set the container element of each image to have fixed height and width and overflow: hidden. Then set the image within to have min-width: 100%, min-height: 100%. Any extra height or width will overflow the container and be hidden.

HTML

<div class="thumb">
    <img src="http://lorempixel.com/400/800" alt="" />
</div>

CSS

.thumb {
    display: block;
    overflow: hidden;
    height: 200px;
    width: 200px;
}

.thumb img {
    display: block; /* Otherwise it keeps some space around baseline */
    min-width: 100%;    /* Scale up to fill container width */
    min-height: 100%;   /* Scale up to fill container height */
    -ms-interpolation-mode: bicubic; /* Scaled images look a bit better in IE now */
}

Have a look at http://jsfiddle.net/thefrontender/XZP9U/5/

Solution 3

I came up with my own solution and thought I would share it here in case anyone else found this thread. The background-size: cover solution is the easiest, but I needed something that would work in IE7 as well. Here's what I came up with using jQuery and CSS.

Note: My images were "profile" images and needed to be cropped to squares. Hence some of the function names.

jQuery:

cropProfileImage = function(pic){
    var h = $(pic).height(),
        w = $(pic).width();

    if($(pic).parent('.profile-image-wrap').length === 0){
                     // wrap the image in a "cropping" div
         $(pic).wrap('<div class="profile-image-wrap"></div>');
    }

      if(h > w ){
          // pic is portrait
          $(pic).addClass('portrait');
          var m = -(((h/w) * 100)-100)/2; //math the negative margin
          $(pic).css('margin-top', m + '%');    
      }else if(w > h){ 
          // pic is landscape
          $(pic).addClass('landscape'); 
          var m = -(((w/h) * 100)-100)/2;  //math the negative margin
          $(pic).css('margin-left', m + '%');
      }else {
        // pic is square
        $(pic).addClass('square');
      }
 }

// Call the function for the images you want to crop
cropProfileImage('img.profile-image');

CSS

.profile-image { visibility: hidden; } /* prevent a flash of giant image before the image is wrapped by jQuery */

.profile-image-wrap { 
      /* whatever the dimensions you want the "cropped" image to be */
      height: 8em;
      width: 8em;
      overflow: hidden; 
 }

.profile-image-wrap img.square {
      visibility: visible;
      width: 100%;  
 }

 .profile-image-wrap img.portrait {
      visibility: visible;
      width: 100%;
      height: auto;
 }

 .profile-image-wrap img.landscape {
      visibility: visible;
      height: 100%;
      width: auto;
 }
Share:
53,304
adit
Author by

adit

Updated on June 13, 2020

Comments

  • adit
    adit almost 4 years

    So I have a collection of thumbnails in my app, which is the size of 200x200. Sometimes the original image doesn't have this ratio so I am planning to crop this image to a square.

    Currently it just streches the image to fit into the thumbnail, so say my original image size is 400x800, then the image looks very squished. I wanted to crop this image so it looks at the shortest width/height and then crop it to a square, so in my example above it will be cropped to a 400x400.

    Is there a way to easily do this via CSS or do I have to use some sort of JS to do this?

  • Mathletics
    Mathletics about 11 years
    What about an image which is wider than it is tall?
  • thefrontender
    thefrontender about 11 years
    @Mathletics then we just update the CSS to set both min-width and min-height to 100% as per this updated Fiddle: jsfiddle.net/thefrontender/XZP9U/5 I've also updated the answer. We lose the ability to scale an image down, but it's still a valid pure CSS solution that fills the square space without distorting the original image
  • Cam
    Cam about 11 years
    Careful this wont work in all browser versions, this is CSS3 markup so unless you are marketing to a particular browser you should consider an alternative approach.
  • Vincent Wasteels
    Vincent Wasteels about 9 years
    is it possible to have centered images ? usually top-left corner doesn't say much...