Css keep image aspect

How to maintain aspect ratio using HTML IMG tag

I am using an img tag of HTML to show a photo in our application. I have set both its height and width attribute to 64. I need to show any image resolution (e.g. 256×256, 1024×768, 500×400, 205×246, etc.) as 64×64. But by setting the height and width attributes of an img tag to 64, it’s not maintaining the aspect ratio, so the image looks distorted. For your reference my exact code is:

In 2022 you probably want this answer: stackoverflow.com/a/66618563/8806907 aspect-ratio is supported by everything except ie: developer.mozilla.org/en-US/docs/Web/CSS/…

16 Answers 16

Don’t set height AND width. Use one or the other and the correct aspect ratio will be maintained.

      

Another option that gives you more flexibility is to use object-fit . This allows fixed dimensions to be set for the img whilst the image itself can be presented in a number of different ways within the defined area.

img < width: 128px; height: 128px; border: 1px solid hotpink; >.none < /* Image is not scaled */ object-fit: none; >.fill < /* Image is scaled to fill the container. */ /* Aspect ratio IS NOT maintained */ object-fit: fill; >.cover < /* Image is scaled to fill the container. */ /* Aspect ratio IS maintained */ object-fit: cover; >.contain < /* Image is scaled to fit within the container. */ /* Aspect ratio IS maintained */ object-fit: contain; >.scale-down < /* Uses either 'none' or 'contain' to produce the smallest image size */ object-fit: scale-down; >
    

This makes no sense for dynamic applications. It is not known whether width or height will be at 64px, as it depends on the ratio of the image. Why is this the upvoted response?

Читайте также:  Python pip как использовать

@Mär This question was about fixed width and/or height images. Responsiveness was not a requirement of the question.

The size is fixed, the aspect ratio is not, as the question was specifically about any image of any resolution. Including resolutions smaller than 64×64.

 

Just a note to people who want to use this solution: object-fit is not very well supported by browsers. It is not supported by IE or Edge at all. Source: caniuse.com/#feat=object-fit

Set width and height of the images to auto , but limit both max-width and max-height :

If you want to display images of arbitrary size in the 64x64px «frames», you can use inline-block wrappers and positioning for them, like in this fiddle.

This worked AFTER I changed the parent to «align-items: center». The default of «align-items: stretch» was taking precedence over «max-height».

This is the correct solution as it continues to be independent of the orientation of the image. 3rror404’s solution requires that you know whether the image is wider than it is tall or vice versa.

An image will be properly restricted by this, but not scaled beyond its original size. Though it is not certain from the opening post which of the two the OP wanted.

Use object-fit: contain in css of html element img .

None of the methods listed scale the image to the largest possible size that fits in a box while retaining the desired aspect ratio.

This cannot be done with the IMG tag (at least not without a bit of JavaScript), but it can be done as follows:

Thanks, @UjjwalSingh. Indeed, we need cover not contain in order to maximize the image size to the largest possible. contain leads to «letterboxing».

There’s a new CSS property aspect-ratio . It sets a preferred aspect ratio for the box, which will be used in the calculation of auto sizes and some other layout functions.

It’s supported in all well spread browsers.
MDN link: https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio
And https://web.dev/aspect-ratio/ contains good examples of using this property

Wrap the image in a div with dimensions 64×64 and set width: inherit to the image:

 

Adding object-fit=»cover» will force the image to take up the space without losing the aspect ratio.

Why don’t you use a separate CSS file to maintain the height and the width of the image you want to display? In that way, you can provide the width and height necessarily.

My site displays a number of photos (with a variety of aspect ratios) and clicking one opens it in a modal. To get it to fit into the modal without cropping, scrolling, or distortion I used the following class on my img tag

You need a div to wrap your image to have a consistente aspect ratio.

You can use the padding-bottom trick to force the div to respect an aspect ratio and a absolute positioned image to fill the space.

The image will be also responsive, taking all the horizontal space available.

.img-frame < width: 100%; padding-bottom: 100%; background: gray; overflow: hidden; position: relative; >.img-frame-4by3 < padding-bottom: 75%; >.img-frame-16by9 < padding-bottom: 56.25%; >.img-frame-5by1 < padding-bottom: 20%; >.img-frame img
 

4:3


16:9


5:1

Welcome to Stack Overflow! I recommend you to read How to answer a question to improve the possibilities to help the user who ask.

The poster is showing a dimension constrained by height in most cases he posted >>> (256×256, 1024×768, 500×400, 205×246, etc.) but fitting a 64px max height pixel dimension, typical of most landscape «photos». So my guess is he wants an image that is always 64 pixels in height. To achieve that, do the following:

This solution guarantees the images are all 64 pixels max in height and allows width to extend or shrink based on each image’s aspect ratio. Setting height to 64 in the img height attribute reserves a space in the browser’s Rendertree layout as images download, so the content doesn’t shift waiting for images to download. Also, the new HTML5 standard does not always honor width and height attributes. They are dimensional «hints» only, not final dimensions of the image. If in your style sheet you reset or change the image height and width, the actual values in the images attributes get reset to either your CSS value or the images native default dimensions. Setting the CSS height to «64px» and the width to «auto» forces width to start with the native image width (not image attribute width) and then calculate a new aspect-ratio using the CSS style for height. That gets you a new width. So the height and width «img» attributes are really not needed here and just force the browser to do extra calculations.

Источник

Maintain image aspect ratio when changing height

Using the CSS flex box model, how can I force an image to maintain its aspect ratio? JS Fiddle: http://jsfiddle.net/xLc2Le0k/2/ Notice that the images stretch or shrink in order to fill the width of the container. That’s fine, but can we also have it stretch or shrink the height to maintain the image proportions? HTML

 
Bacn Bacn Bacn Bacn

As far as I know, the best solution is to use a

with the CSS background-image: url(. );background-size:contain; background-repeat:no-repeat

There are some interesting leads here, but what about when the images aren’t already the same ratio? Adding and ‘extra’ div, is the last thing we need to worry about. Why not use a test case like this instead: jsfiddle.net/sheriffderek/999Lg9qv

9 Answers 9

To keep images from stretching in either axis inside a flex parent I have found a couple of solutions.

You can try using object-fit on the image which, e.g.

Or you can add flex-specfic rules which may work better in some cases.

align-self: center; flex: 0 0 auto; 

For img tags if you define one side then other side is resized to keep aspect ratio and by default images expand to their original size.

Using this fact if you wrap each img tag into div tag and set its width to 100% of parent div then height will be according to aspect ratio as you wanted.

I know there are two answers that suggest using divs, but I am marking this answer correct because it explains why the image heights are different than I expected. In fact, this is normal & correct behavior, and is unlikely to be «fixed», since it is not a bug.

But this answer doesn’t talk anything about flexbox, because images do behave differently within flexbox container. Setting one side will not proportionally resize the other. Wrapping them in non flexbox container helps but that adds unnecessary markup losing semanticity.

But, what about this? jsfiddle.net/xLc2Le0k/15 I think that this solution is a fluke that only works because the images are all the same ratio. side note: there isn’t any ‘semanticity’ lost by placing an image in a div for positioning / especially when dealing with responsive images.

No need to add a containing div.

The default for the css «align-items» property is «stretch» which is what is causing your images to be stretched to its full original height. Setting the css «align-items» property to «flex-start» fixes your issue.

Ahh. thanks for actually doing things the supported way. I was reading the answers until that one and couldn’t believe all we had were dirty hacks..

Most of images with intrinsic dimensions, that is a natural size, like a jpeg image. If the specified size defines one of both the width and the height, the missing value is determined using the intrinsic ratio. — see MDN.

But that doesn’t work as expected if the images that are being set as direct flex items with the current Flexible Box Layout Module Level 1, as far as I know.

See these discussions and bug reports might be related:

  • Flexbugs #14 — Chrome/Flexbox Intrinsic Sizing not implemented correctly.
  • Firefox Bug 972595 — Flex containers should use «flex-basis» instead of «width» for computing intrinsic widths of flex items
  • Chromium Issue 249112 — In Flexbox, allow intrinsic aspect ratios to inform the main-size calculation.

As a workaround, you could wrap each with a or a , or so.

.slider < display: flex; >.slider>div < min-width: 0; /* why? see below. */ >.slider>div>img
 

4.5 Implied Minimum Size of Flex Items

To provide a more reasonable default minimum size for flex items, this specification introduces a new auto value as the initial value of the min-width and min-height properties defined in CSS 2.1.

Alternatively, you can use CSS table layout instead, which you’ll get similar results as flexbox , it will work on more browsers, even for IE8.

.slider < display: table; width: 100%; table-layout: fixed; border-collapse: collapse; >.slider>div < display: table-cell; vertical-align: top; >.slider>div>img
 

The flexbox spec introduced a new auto value as the default value for min-width and min-height (previously it was 0 ). Chrome does not implement it yet, so your first snippet works. But new browsers need it in order to allow the flex items to shrink smaller than the default width of the images.

+1 this should be accepted answer because it talks about images in flexbox model which is the root problem in this case.

Table is great if your layout doesn’t change at various break-points, but that is unlikely these days.

I have been playing around flexbox lately and i came to solution for this through experimentation and the following reasoning. However, in reality I’m not sure if this is exactly what happens.

If real width is affected by flex system. So after width of elements hit max width of parent they extra width set in css is ignored. Then it’s safe to set width to 100%.

Since height of img tag is derived from image itself then setting height to 0% could do something. (this is where i am unclear as to what. but it made sense to me that it should fix it)

DEMO

(remember saw it here first!)

Источник

Оцените статью