Description
Demonstration and tests of proportional image scale with CSS
Date of the Tutorial
Sun Aug 16 11:10:30 2009
Demonstration and tests of proportional image scale with CSS
Sun Aug 16 11:10:30 2009
A lot of people seem to wonder about just how to proportionally scale images with CSS; for the image to fit into FOO x BAR container... Thing is, a browser is not a graphics application and CSS isn't a graphics API. What it means is that you can't do that with CSS!
What you CAN do, however, is have the <img> proportionally scale within one-axis limit. What I mean by that, is that you can make large images smaller and smaller images larger by setting a specified width or max-width while leaving the height to be scaled proportionally to width. Turning it around, you can use the height constrains while leaving the width scale proportionally. You can't have both at the same time.
In this short tutorial, I'll first show you how to do what I just explained and later on will show you some "tests" that fail in proportional image resize.
The example shows the scaling using the Y-axis, i.e. image scales according to container's height. The same principle applies for resizing on Y-axis; scaling up to container's width, just never both axis together. Let's have a look:
Original image:
Same image scaled up to the container's height:
Same image scaled down to the container's height:
<div> <img src="/pics/hl_logo.png" alt="" width="95" height="115"> </div> <div id="scale-up" style="height: 230px"> <img src="/pics/hl_logo.png" alt=""> </div> <div id="scale-down" style="height: 57px"> <img src="/pics/hl_logo.png" alt=""> </div>
img { vertical-align: middle; height: 100%; } #scale-up { height: 230px; } #scale-down { height: 57px; }
What do we see here? For those wondering why I am applying vertical-align to the image, read this Images, And Mysterious Gaps page, it's not relevant to image scale. I've set { height: 100%; } on the image for its height to be 100% of container's height, since in the first example (original image) I haven't set any height on the container the image appears at its original size.
An important thing to note here is that I removed the width="" and height="" attributes from <img> element in the scaling examples. This is necessary as specifying those will prevent the image from being scaled proportionally.
That's pretty much all there is to it. The set height on the container specifies the height of the image - scaling it if necessary - and the width of the image is scaled in proportion; same would happen if we would to swap widths and in the examples.
I'd like to add one more thing, if you want to only scale the images down then use max-height property, i.e. img { max-height: 100%; } (or max-width for that matter); whilst those properties are not supported in IE6 (see my Max-Width Workaround and Max-Height Workaround tutorials) in the browsers that do support them, your images will only be scaled when their height (or width, depending on which one you're using) exceeds that of the container, leaving smaller images at their original size.
Originally, I wanted to post each of the tests that I was doing right on this page along with the code, but then I decided that it's not worth my time, considering that virtually every method, except for what I've described in this tutorial, fails.
What I did, is I uploaded a all those tests on one page for you to take a look. Read the source, Luke!
Fri Nov 4 16:33:39 2011
@monty , thanks mate, that was exactly what I needed for a joomla to iphone app port. For me my width is constrained, but needed to be larger in the app, and setting the height to inherit worked like a charm. thanks to all.
Wed Aug 3 21:30:07 2011
I know this post is dated, but I stumbled on it, and thought I might add that for people using a cms like Wordpress or the like, the width and height are automagically added in image attributes. To work around this and contrain images, all you need to do is width:auto and/or height:auto in the css. I've only tested this in FF, but I'm pretty sure it'll work in most modern browsers, and will let you constrain the image on a single axis.
Mon Jul 4 09:58:08 2011
I have figured a simple way around this. It seems to be working on all (modern) browsers.
<div>
<img style="width: 80px; height: inherit;" src="me.jpg" />
</div>
The way this works is that the parent div it is inheriting from itself has no defined attribute, and is the size of the contained image itself. The argument seems recursive but meh, it does the job.
Mon Jun 6 23:02:20 2011
Your examples only work if you know the size of the image and container in advance.
If you have an image that is inherently this size:
100px x 80px
And put it in a container like this:
<div height="100px" width="50px">
<img src="a.png" height="100%">
</div>
Then the width will expand past the size of the container. In this case you have to know to set the height to 100% instead, because of the circumstances.
Is there a better automatic solution that you know of?
It seems that you make a JavaScript function to resize the image, and bind it to all events that would during a resize of the container.
Fri May 27 16:32:51 2011
I think the problem is scaling, not merely constraining. (been a long while since I wrote this...)
Fri May 27 15:40:40 2011
I tried my hand at this, and I'm not sure I understand what the problem is:
http://fiddle.jshell.net/rpZkR/3/show/light/
As you can see, specifying max-width and max-height, even together, works just fine for me. I was able to constrain the given image into both a 600x200 container and a 200x600 container while preserving the image's aspect ratio.
What am I missing?
Tue Apr 5 19:30:50 2011
That was amazing!!!
I was looking for a solution to that problem for the past 2 months!!!
Thanks a lot!!!
Tue Mar 22 08:37:10 2011
it works you saved my life thanks
Tue Mar 8 16:21:59 2011
I wrote this a while back, so my memory is fuzzy; however, I think this tut just lists some of the possibilities and mentions what doesn't work where.
If it doesn't, try for yourself (I don't remember anymore) and post the results in the comments. Thanks!
Tue Mar 8 14:24:25 2011
Hows the compatibility like on this? does it work on ie6?
Thu Feb 17 21:50:31 2011
Thanks , it's really help me in my current project... :D
Sun Oct 31 11:36:49 2010
Thank you! it works exactly as I wanted it!
Fri Oct 15 17:28:21 2010
Daniel, in most cases one wants to set *maximum* dimensions (i.e. both width and height) and have the image automatically fit into those.
This page simply lists various experiments trying to incorporate that idea.
Fri Oct 15 13:11:02 2010
I don't know why all this code would be needed. In every browser I tried, setting one dimension via CSS scaled the image proportionally in the other dimension. No need for all these extra CSS properties.
Mon Aug 30 09:05:20 2010
Thanks for explaining this so concisely!
Wed Aug 25 13:47:23 2010
You sir are a genius.
Mon Aug 23 15:24:08 2010
Great idea! also got it to work with a pixel size for times you do not have a wrapper div available to you.
img {
height: inherit;
width: 100px;
}
Wed May 12 11:04:39 2010
Thank you!! Really simple, but really useful--thanks for pointing it out.
Sun Feb 7 11:00:11 2010
"An important thing to note here is that I removed the width="" and height="" attributes from <img> element in the scaling examples. This is necessary as specifying those will prevent the image from being scaled proportionally."
Not entirely true. Since comparable CSS rule sets ('width'/'height') overwrite any HTML 'width'/'height' attribute values, by placing an 'auto' value on the opposing axis to which you specifiy a length, the replaced element will continue to retain it's inherent aspect ratio (if indeed there is one).
Another thing to note is that scaling a replaced element in the context you describe is in fact OPTIONAL as per CSS 2.1 [1]
[1] http://lists.w3.org/Archives/Public/www-style/2009Nov/0324.html, http://lists.w3.org/Archives/Public/www-style/2009Dec/0322.html
Tue Dec 29 15:16:46 2009
Thanks for providing these examples. They've been just what I need for a client project I'm working on!
If you found materials on this site useful, please consider donating a few bucks to the author. Thank you.
Alternatively, purchase my book: 