Reduce image size and maintain CSS aspect ratio

Asked

Viewed 309,745 times

36

If I have a horizontal image (320x205),

<div class="container">
    <img src="imagem.jpg" width="320" height="205" />
</div>

and I put the CSS rule .container img { max-width: 200px; }, the reduction is not proportionate:


And put yourself { max-width: 200px; max-height: 150px } goes wrong with horizontal and vertical images. How to hit this?

.container img {
    max-width: 200px;
    max-height:250px;
}
.container {
    clear: both;
    margin-top: 20px;
}
img {
    vertical-align: top
}
<h2>Imagem horizontal</h2>
ORIGINAL: <img src="http://upload.wikimedia.org/wikipedia/commons/7/75/Zacharias_Wagner_-_Mameluca.jpg" width="320" height="205">
<div class="container">MAX-WIDTH: <img src="http://upload.wikimedia.org/wikipedia/commons/7/75/Zacharias_Wagner_-_Mameluca.jpg" width="320" height="205" /></div>

<h2>Imagem vertical</h2>
ORIGINAL: <img src="http://upload.wikimedia.org/wikipedia/commons/4/44/Docteur_Piron_-_La_Bonite.JPG" width="241" height="400">
<div class="container">MAX-WIDTH: <img src="http://upload.wikimedia.org/wikipedia/commons/4/44/Docteur_Piron_-_La_Bonite.JPG" width="241" height="400" /></div>

  • 2

    Good. I was under the impression that this has already been asked, but I could not find the supposed duplicate.

  • @bfavaretto, yeah, I swear I looked for a duplicate...

  • I think the closest is this: http://answall.com/questions/26003 (+ the utluiz response). But your question is so much simpler and more objective, that I prefer to keep it as canonical.

  • Had seen this. Yes, the thing is complicated there. And as I saw nothing talking about auto nor of max-*....

8 answers

52


Lack of value auto to the width and height. So the scale is made according to width or height (what reaches first) and the ratio is made automatically.

.container img {
    max-width:200px;
    max-height:150px;
    width: auto;
    height: auto;
}

.container img {
    max-width: 200px;
    max-height:250px;
    width: auto;
    height: auto;
}
.container {
    clear: both;
    margin-top: 20px;
}
img {
    vertical-align: top
}
<h2>Imagem horizontal</h2>
ORIGINAL: <img src="http://upload.wikimedia.org/wikipedia/commons/7/75/Zacharias_Wagner_-_Mameluca.jpg" width="320" height="205">
<div class="container">MAX-WIDTH: <img src="http://upload.wikimedia.org/wikipedia/commons/7/75/Zacharias_Wagner_-_Mameluca.jpg" width="320" height="205" /></div>

<h2>Imagem vertical</h2>
ORIGINAL: <img src="http://upload.wikimedia.org/wikipedia/commons/4/44/Docteur_Piron_-_La_Bonite.JPG" width="241" height="400">
<div class="container">MAX-HEIGHT: <img src="http://upload.wikimedia.org/wikipedia/commons/4/44/Docteur_Piron_-_La_Bonite.JPG" width="241" height="400" /></div>

  • Declare the value auto would be redundant, since they are standard values.

19

'Solution' using Jquery: Replace the element IMG by another that supports background, such as DIV. Pass the value of src for background-image, as well as tag width and height values IMG original:

$('.container img').replaceWith(function(i, v){
    return $('<div/>', {
        style: 'background-image: url(' + this.src + ');' + 
        'width:' + this.width + 'px;' + 
        'height:' + this.height + 'px;' ,
        class: 'fakeImg'
    })
})

Adjust the property value background-size for cover, and adjust positioning to centralized:

.container .fakeImg {
    background: no-repeat center;
    background-size: cover;    
}

.container
{
    display:inline-block;
    border:2px solid red;
    margin: 4px;
}

With this, you will have a false DIV element that allows proportional image cutting so that it fits exactly in the dimensions indicated in the element IMG original:

inserir a descrição da imagem aqui

Example in Fiddler.

  • Interesting, but the image gets 100x100px and loses the ratio...

  • @brasofilo I updated the example - the proposal is maintained yes, you can check. =)

  • Ah, boy, your trick makes a Crop! Cool :))

  • @brasofilo plus a little update on Jsfiddle to make it clearer. Check there!

  • good even that, great technique :D

11

In CSS there is still the property object-fit defining how an object should behave towards an element with defined dimensions. For example, let’s consider a square element with 100 px of side and a image with 1280x720 px.

The property can receive several values:

  • fill, fills the entire element with the image content, keeping the dimensions defined for the element, not the image ratio;

div {
  border: 1px solid black;
  width: 100px;
  height: 100px;
}

img {
  width: 100px;
  height: 100px;
  object-fit: fill;
}
<div>
  <img src="https://i.ytimg.com/vi/_PKF6UPtmhk/maxresdefault.jpg">
</div>

  • contain, fills the entire element with the largest dimension of the image, adapting the smallest dimension according to the original ratio;

div {
  border: 1px solid black;
  width: 100px;
  height: 100px;
}

img {
  width: 100px;
  height: 100px;
  object-fit: contain;
}
<div>
  <img src="https://i.ytimg.com/vi/_PKF6UPtmhk/maxresdefault.jpg">
</div>

  • cover, fills the entire element with the smallest dimension of the image, adapting the largest dimension according to the original ratio, hiding the content of the image that exceeds the dimensions of the element;

div {
  border: 1px solid black;
  width: 100px;
  height: 100px;
}

img {
  width: 100px;
  height: 100px;
  object-fit: cover;
}
<div>
  <img src="https://i.ytimg.com/vi/_PKF6UPtmhk/maxresdefault.jpg">
</div>

  • none, fills the element with the image in its original size, hiding the content that exceeds the element’s dimensions;

div {
  border: 1px solid black;
  width: 100px;
  height: 100px;
}

img {
  width: 100px;
  height: 100px;
  object-fit: none;
}
<div>
  <img src="https://i.ytimg.com/vi/_PKF6UPtmhk/maxresdefault.jpg">
</div>

  • scale-down, the image will be adapted to its smallest version among the results of none or contain;

div {
  border: 1px solid black;
  width: 100px;
  height: 100px;
}

img {
  width: 100px;
  height: 100px;
  object-fit: scale-down;
}
<div>
  <img src="https://i.ytimg.com/vi/_PKF6UPtmhk/maxresdefault.jpg">
</div>


The property support object-fit is relatively tall, with the exception of the IE/Edge family:

inserir a descrição da imagem aqui

  • Well completed the example! Thanks for the contribution!

  • Very good this! I’m just wondering why the img { } is set to 100x100px in CSS, the object-fit will consider that as the area to be filled? In that case, what is the reason for the div container also have 100x100px?

4

4

Imgliquid Plugin: https://github.com/karacas/imgLiquid

Resources:

  • Uses background-size CSS information
  • Compatible with Bootstrap
  • Small size < 2KB (gzip)
  • Fill / Crop
  • Responsive
  • Svg Support
  • Callbacks
  • HTML data attributes-*
  • All browsers (Inc. ie6)

1

I fought a lot with this problem. Generically the solution is to put the img inside a div, and limit only the width of the div containing the image. The image must have "width: 100%". Thus, the image will be proportional, and the width of the div.

This container div must have the width well defined, it can be both in pixels and in percentage, but there must be a width.

Follow my CSS, I use two divs, one inside the other, for reasons that I will describe below. The outermost div (cartimg) is 55% page wide and centralizes thanks to "margin: auto", but you could use float or another method to position the div.

#body div.cartimg {
        margin: auto;
        width: 55%;
        text-align: center;
}

#body div.cartimg div.cartimg2 {
        width: 100%;
        margin: auto;
        text-align: center;
        padding: none;
}

#body div.cartimg img {
        width: 100%;
        margin-left: 0em;
        margin-top: 0em;
        margin-right: 0em;
        margin-bottom: 0em;
}

An additional problem I faced was this: I have images of different widths and heights, and I would like to limit the size of the image in both dimensions. A wide image can occupy 55% of the width, but a very narrow image would be "stretched" to cover 55% and would be very long in the vertical direction. This is particularly unpleasant on a mobile screen.

One solution is to manually change the image size (width less than 100%), another is to recalculate using Javascript (dynamically), the solution I adopted was to calculate the image ratio in PHP and change the width cartimg2 container so as to limit its height, if the image is higher than 16:9. (Attempts to directly limit the height did not go very well.)

Follow the relevant PHP code:

function get_container_width($addr)
{
        $tallest = 16.0 / 9.0;

        $container_width = 100;

        if ($addr[0] == '/') {
                $addr = $_SERVER["DOCUMENT_ROOT"] . $addr;
        }

        list($width, $height) = getimagesize($addr);
        if ($width > 0 && $height > 0) {
                $prop = $width / $height;
                if ($prop < $tallest) {
                        // image is 'tall', or thin
                        // we need to limit width to limit height indirectly
                        $container_width *= $prop / $tallest;
                }
        }

        return $container_width;
}

    $container_width = get_container_width($addr);

    echo("<div id='$name' class=cartimg>");
    echo("<div id='hdiv_$name' style='width: $container_width%;' class=cartimg2>\n");
    echo("<a href='$addr' class=noarrow>\n");
    echo("<img src='$addr' alt='$desc'>\n");
    echo("</a>\n");
    echo("</div>");
    echo("<i>$desc</i>\n");
    echo("</div>");

The solution using background image instead of img also works to limit height and width, only there you are playing the Web semantics out (Google finds the images by the img tag, and their descriptions by the alt attribute).

-1

simple..

you file the width you want at most as 100% of the div in which the image is contained.. and the height you place as auto ! Important;

example:

#apresentacao-texto-loop img {width:100%;height:auto !important;}

I always put it like this and resize proportionally ;)

-2

You can set the minimum and maximum size to equal, so the image will always have the same ratio. For example:

.give-wrap .give-card__media img {
display: block;
margin: 0 auto;
object-fit: cover;
order: 1;

    max-width:300px;
    max-height:300px;
    min-height:300px; 
    min-width:300px;
width: auto;
height: auto;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.