hasLayout.net

Share |

CSS Proportional Image Scale

Description

Demonstration and tests of proportional image scale with CSS

Date of the Tutorial

Sun Aug 16 11:10:30 2009

Overview

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.

Proportional Scale of Images Using One Axis

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:

HTML Code:
<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>
CSS Code:
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.

Various [Failing] Scale Tests

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!

Comments

Create new comment
  • 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.

  • Jason

    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.

  • Angad

    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.

  • Neil Hooe

    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.

  • Zoffix Znet

    Fri May 27 16:32:51 2011

    I think the problem is scaling, not merely constraining. (been a long while since I wrote this...)

  • Aseem Kishore

    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?

  • Pedro

    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!!!

  • Serdar

    Tue Mar 22 08:37:10 2011

    it works you saved my life thanks

  • Zoffix Znet

    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!

  • Karim

    Tue Mar 8 14:24:25 2011

    Hows the compatibility like on this? does it work on ie6?

  • Vitorio Santosa

    Thu Feb 17 21:50:31 2011

    Thanks , it's really help me in my current project... :D

  • Ivan

    Sun Oct 31 11:36:49 2010

    Thank you! it works exactly as I wanted it!

  • Zoffix Znet

    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.

  • Daniel

    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.

  • Joe

    Mon Aug 30 09:05:20 2010

    Thanks for explaining this so concisely!

  • Brian Hanson

    Wed Aug 25 13:47:23 2010

    You sir are a genius.

  • Monti

    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;
    }

  • Geoff

    Wed May 12 11:04:39 2010

    Thank you!! Really simple, but really useful--thanks for pointing it out.

  • James Hopkins

    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

  • Sarah Lewis

    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:

Support Wikipedia