Eduardo Torres
Eduardo Torres

Reputation: 43

Changing aspect ratio of a image without cropping

i'm with a trouble in relation with treatment of image, using intervention image on laravel. The problem is: I have to change aspect ratio of a image, but, in my current way, i'm cropping the image to do it, and important things in this element is being cropped too. So, i was wondering, is it possible add border around on image to create the aspect ratio? If you all would can help me, i'll would be very glad with that.

P.S. Sorry for my english, i'm still learning, haha.

Upvotes: 1

Views: 531

Answers (1)

Mr. Hugo
Mr. Hugo

Reputation: 12592

Solution 1

Create a div with the right aspect ratio/dimensions and load the image as a background image with background-size: contain.

div {width: 300px; max-width: 100%;}
div > div {
  width: 100%; 
  padding-bottom: 60%; /* use this for the aspect ratio */
  background: black url('http://jekyllcodex.org/uploads/grumpycat2.jpg') center center no-repeat;
  background-size: contain;
}
<div><div></div></div>

Working demo: https://codepen.io/anon/pen/ooBaKe

How it works

The padding bottom creates the height for this div (as it has no content). The padding-bottom percentage is the percentage of the width of the parent. Thus, a 2:1 ratio image has a padding-bottom of 50%. A 3:2 ratio image has a padding-bottom of 66.66%.

Why this works

The div inside this div has a width of 100%. This is 300px, as the child div is constrained by its parent. The padding bottom percentage is relative to containing block, and not (as many people think) to the body. Here the containing block is the nearest block-level ancestor, which is the parent element. Note that it would be relative to the body if we used just one div with a fixed width of 300px.

Why this solution is not perfect

This solution is fully responsive, due to the max-width of 100% on the containing div. And if you change your mind and you want images to be cropped instead of contained, you only need to change the background-size to 'cover'. Therefore this looks like a good solution. However, a background images is not a proper image, as it has no 'alt' text and lacks a DOM representation, resulting in all kinds of accessibility problems.


Solution 2

Create a div with the right aspect ratio/dimensions and load the image as img tag with max-width and max-height.

HTML

div {
  width: 300px; 
  max-width: 100%; 
  position: relative;
}
div > div {
  width: 100%; 
  padding-bottom: 110%; /* use this for the aspect ratio */
  background: black;
}
div > div > img {
  max-width: 100%; 
  max-height: 100%; 
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
<div>
  <div>
    <img src="http://jekyllcodex.org/uploads/grumpycat2.jpg" />
  </div>
</div>

Working demo: https://codepen.io/anon/pen/yPgQKJ

About this solution

It works roughly in the same way as the previous one, but this solution is semantically correct. The difference here is that an image element is positioned absolute in the inner div. Its placement is absolute, but relative to its parent at 50% of the left border and 50% of the top. Then the image placement is corrected for its width and height, using the translate function of CSS (otherwise its top left corner would be in the middle of its parent). Because only max-width and max-height are used (and not width and height), the image stays responsive and keeps its aspect ratio.

Upvotes: 3

Related Questions