CSS image resize percentage of itself?

I am trying to resize an img with a percentage of itself. For example, I just want to shrink the image by half by resizing it to 50%. But applying width: 50%; will resize the image to be 50% of the container element (the parent element which maybe the <body> for example).

Question is, can I resize the image with a percentage of itself without using javascript or server side? (I have no direct information of the image size)

I am pretty sure you cannot do this, but I just want to see whether there are intelligent CSS only solution. Thanks!


Solution 1:

I have 2 methods for you.

Method 1. demo on jsFiddle

This method resize image only visual not it actual dimensions in DOM, and visual state after resize centered in middle of original size.

html:

<img class="fake" src="example.png" />

css:

img {
  -webkit-transform: scale(0.5); /* Saf3.1+, Chrome */
     -moz-transform: scale(0.5); /* FF3.5+ */
      -ms-transform: scale(0.5); /* IE9 */
       -o-transform: scale(0.5); /* Opera 10.5+ */
          transform: scale(0.5);
             /* IE6–IE9 */
             filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.9999619230641713, M12=-0.008726535498373935, M21=0.008726535498373935, M22=0.9999619230641713,SizingMethod='auto expand');
}​

Browser support note: browsers statistics showed inline in css.

Method 2. demo on jsFiddle

html:

<div id="wrap">
    <img class="fake" src="example.png" />
    <div id="img_wrap">
        <img class="normal" src="example.png" />
    </div>
</div>​

css:

#wrap {
    overflow: hidden;
    position: relative;
    float: left;
}

#wrap img.fake {
    float: left;
    visibility: hidden;
    width: auto;
}

#img_wrap {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

#img_wrap img.normal {
    width: 50%;
}​

Note: img.normal and img.fake is the same image.
Browser support note: This method will work in all browsers, because all browsers support css properties used in method.

The method works in this way:

  1. #wrap and #wrap img.fake have flow
  2. #wrap has overflow: hidden so that its dimensions are identical to inner image (img.fake)
  3. img.fake is the only element inside #wrap without absolute positioning so that it doesn't break the second step
  4. #img_wrap has absolute positioning inside #wrap and extends in size to the entire element (#wrap)
  5. The result of the fourth step is that #img_wrap has the same dimensions as the image.
  6. By setting width: 50% on img.normal, its size is 50% of #img_wrap, and therefore 50% of the original image size.

Solution 2:

HTML:

<span>
    <img src="example.png"/>
</span>

CSS:

span {
    display: inline-block;
}
img {
    width: 50%;
}

This has got to be one of the simplest solutions using the container element approach.

When using the container element approach, this question is a variation of this question. The trick is to let the container element shrinkwrap the child image, so it will have a size equal to that of the unsized image. Thus, when setting width property of the image as a percentage value, the image is scaled relative to its original scale.

Some of the other shrinkwrapping-enabling properties and property values are: float: left/right, position: fixed and min/max-width, as mentioned in the linked question. Each has its own side-effects, but display: inline-block would be a safer choice. Matt has mentioned float: left/right in his answer, but he wrongly attributed it to overflow: hidden.

Demo on jsfiddle


Edit: As mentioned by trojan, you can also take advantage of the newly introduced CSS3 intrinsic & extrinsic sizing module:

HTML:

<figure>
    <img src="example.png"/>
</figure>

CSS:

figure {
    width: intrinsic;
}
img {
    width: 50%;
}

However, not all popular browser versions support it at the time of writing.

Solution 3:

Please note that this answer is 10+ years old and outdated.


Try zoom property

<img src="..." style="zoom: 0.5" />

Edit: Apparently, FireFox doesn't support zoom property. You should use;

-moz-transform: scale(0.5);

for FireFox.