img width relative to containing div - html

Original Question
What is the most efficient way to calculate the width of an image relative to it's containing div in css?
I have the following snippet which sets #image1.width to a percentage that is relative to the width of its parent. I'm using a percentage because I need the image to scale proportionately to the parent when the screen is resized.
div {
position: relative;
display: block;
width: 100%;
}
#image1 {
position: absolute;
left: 10%;
top: 10%;
width: 29.43%;
height: auto;
}
#under {
width: 100%;
}
<div>
<img id="image1" src="http://placehold.it/206x115">
<img id="under" src="http://placehold.it/700x300/ff00f0/ffffff">
</div>
It is currently working as intended, except that I have to manually calculate the width percentage for every single image. i.e.
#image1 dimensions == 206x115
#under dimensions == 700x300
new #image1.width % == #image1.width / #under.width == 206/700 == ~29.43%
What I want to know is if there id a calc() method or similar I can implement to ease/streamline this process?
I was going to use width: calc(100% / 700) however this obviously will not work when the screen size changes.
Goals
To re-iterate, it is imperative that the #under image scales with the screen size and the #image remains proportionate.
I want the natural image ratios preserved with one another (i.e. an image that is one quarter the size of the other will remain as such at all browser widths).
Note: The html can be reconfigured in any way to achieve this.
Target browsers: Chrome, Firefox, Edge.
Post Bounty Review
Comment on #Obsidian Age's answer (end of first bounty 31.03.17):
Unfortunately #Obsidian Age's answer is not correct - it is close but not quite and I just wanted to clarify this here... Below is a snippet from his answer... Note that I think it is a good answer, just clarifying why it has not been accepted:
:root {
--width: 90vw; // Must be viewport-driven
}
#image1 {
width: calc(var(--width) / 3); // The 3 can be replaced with any float
}
Setting --width: 90vw what happens if body or div have a max-width set? This is also very hard to calculate for all devices when factoring in viewport-scaling.
#image1 { width:calc(var(--width) / 3); } This equates to calc(90vw / 3) which is 30vw which would equate to 30% of the images width. But how do we work out the number to divide by? Well it's back to where we started... width:calc(var(--width) * calc(206/700*100)); And this is why I have not accepted this answer.

Unfortunately, CSS has no parent selector. While you can't make an element relative to the parent directly with CSS, what you can do with pure CSS is set a variable that both elements make use of:
:root {
--width: 90vw; // Must be viewport-driven
}
Now you can use this variable as both the (fixed) width of the parent element, and the calculation-driven width of the child:
#under {
width: var(--width);
}
#image1 {
width: calc(var(--width) / 3); // The 3 can be replaced with any float
}
Note that the variable must either be a fixed unit, or be relative to the viewport. If it were percentage-based, both #under and #image1 would base their width off of their respective parents. In order to have this work responsively, it must be based off of the viewport.
:root {
--width: 90vw;
}
div {
position: relative;
display: block;
width: 100%;
}
#image1 {
position: absolute;
left: 10%;
top: 10%;
width: calc(var(--width) / 3);
height: auto;
}
#image2 {
position: absolute;
left: 25%;
top: 10%;
width: 10%;
height: auto;
}
#under {
width: var(--width);
}
<div>
<img id="image1" src="http://placehold.it/206x115">
<img id="under" src="http://placehold.it/700x300/ff00f0/ffffff">
</div>
I've also created a JSFiddle of this here, where you can see both elements scale when the viewport resizes.
Hope this helps! :)

I realize that the question prompts for a pure CSS solution, but I liberally interpreted that as meaning "no JavaScript".
In that vein, here's a solution using an embedded SVG:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" viewBox="0 0 700 300">
<image x="0" y="0"
xlink:href="http://placehold.it/700x300/ff00f0/ffffff"/>
<image x="10%" y="10%"
xlink:href="http://placehold.it/206x115"/>
</svg>

The best approach I think would be to eliminate width & use scale to fit the div, but the problem is scale transform do not accept any unit value, such as % or px or vw/vh!
.common_img_class{
transform: scale(calc(100vw/700)); /* this won't work! */
/* Idea here is to let image take is original width & then scale with respact to base image scaling. Base image scaling is detenined by *window_width/base_image _width*, here base image width is 700 as per you example */
}
Thus second best I can think of is to eliminate manual calculation of percent. Use calc() function to do that for you.
#firsrt_img{
width: calc((206/700) * 100%);
}
#second_img{
width: calc((306/700) * 100%);
}
Here you still have to write width for all but atleast spared from percent or ratio calculation.
Note:
If anyone can help with first approach, their inputs are welcome.

One thing that might work, if you are willing to use bootstrap (https://getbootstrap.com/examples/grid/):
<!-- parent -->
<div class="row">
<div class="col-md-6">
<img src="">
<!-- this is 50% of the screen for min 992px, a full line otherwise -->
</div>
<div class="col-md-3">
<img src="">
<!-- this is 25% of the screen for min 992px, a full line otherwise-->
</div>
<div class=col-md-3>
<img src="">
<!-- this is 25% of the screen for min 992px, a full line otherwise -->
</div>
</div>
You can group these as you want/need, just remember that the numbers have to add to 12 (in my example, 6+3+3). You can achieve a 100% width effect using col-md-12. Also, the md infix is just one of several options of cutoff between putting everything on the same line and stacking elements. You can check out http://getbootstrap.com/css/#grid for more details, as well as a couple of examples.

Inspired by the answer of Robby Cornelissen, here is an approach that works in the targeted browsers currently. Its only drawback is that the dimensions of the images have to be specified in the HTML (well, the SVG really) explicitly.
Here is a demo.
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" viewBox="0 0 700 300">
<image x="0" y="0" width="700" height="300"
xlink:href="http://placehold.it/700x300/ff00f0/ffffff"/>
<image x="10%" y="10%" width="206" height="115"
xlink:href="http://placehold.it/206x115"/>
</svg>
The approach, like Robby's answer, uses the SVG image element. That currently defaults to having zero width and height when no dimensions are specified explicitly, but will change in SVG 2. This means that as soon as SVG 2 is supported by browsers, instead of specifying the image dimensions, we could set width="auto" height="auto" and be done.
The value auto for width and height on the ‘image’ element is calculated from the referenced image's intrinsic dimensions and aspect ratio, according to the CSS default sizing algorithm.
— SVG 2 Editor's Draft, § 7.8. Sizing properties: the effect of the ‘width’ and ‘height’ properties. Accessed 2017-12-18.

Related

Is it possible to use pure CSS to set <img> height according to its 100% width if the widht/height ratio is fixed?

I have some HTML like this:
<div id="wrap">
<p>blah blah ... </p>
<img style="width:100%" src="..." />
<p>blah blah ... </p>
</div>
The image would “flash” before its rendering - because its height is 0 if you don't declare it in the CSS. This is very annoying for my users.
However, I tried something like this:
img {height:calc(width/2)}
or this:
img {height:50%}
It's not working.
I have many pages like this and all the images are in a 2:1 width/height ratio.
Is there anything I can do in Pure CSS to make the image element as big as of the rendered size, so that before its loading, it won't break the page's layout.
By “Pure CSS” I mean, there should not be extra JavaScript or HTML. For instance, the img is the child of div#wrap and I want it remains this way.
Update:
I found another answer suggest me to use calc(100vw * .5). However, this doesn't solve my question. 100vw is a fixed width - the width of the viewport. What I want is something like calc(100 * this(width) * .5).
Thanks
To avoid Cumulative Layout Shift while the image is loading you would need to use a wrapper. I know this is not what you asked for but as far as I am aware there is no other way than to alter the HTML.
The trick is to create a 0 height wrapper with padding the same height as your aspect ratio.
So in the example below I have 3 images with an aspect ratio of 16:9 (or 2:3). As such I create container with the correct padding height using calc(100% * 2/3).
This will then be covered by the image once it loads.
The .container is purely to let you see all the images load in.
It does rely on your knowing the image aspect ratio before it loads.
.container{
width: 15%;
}
.image-wrapper {
width: 100%;
height: 0;
padding-bottom: calc(100% * 2 / 3);
position: relative;
border: 2px solid #333;
}
.image {
width: 100%;
position: absolute;
}
<div class="container">
<div class="image-wrapper">
<img class="image" src="https://placehold.it/3000x2000.jpg" />
</div>
<div class="image-wrapper">
<img class="image" src="https://placehold.it/4500x3000.jpg" />
</div>
<div class="image-wrapper">
<img class="image" src="https://placehold.it/3750x2500.jpg" />
</div>
</div>
Chrome and Firefox
Chrome and Firefox has both introduced native aspect ratio space saving (I do not know the proper name for it as you can probably tell!)
If you give you image a width and height the browser will allocate space for it, even if the image itself is a different size than specified.
please note - you must give the image a width and height of 100% for this to work.
Notice how in the following example the widths and heights I have set are aspect ratio relevant but do not affect the container size. Obviously set these widths and heights to something more sensible in production.
.container{
width: 15%;
}
.image{
border: 2px solid #333;
width: 100%;
height: 100%;
}
<div class="container">
<img class="image" src="https://placehold.it/3000x2000.jpg" width="6" height = "4"/>
<img class="image" src="https://placehold.it/4500x3000.jpg" width="3" height = "2"/>
<img class="image" src="https://placehold.it/3750x2500.jpg" width="3750" height = "2500"/>
</div>
You need to have both attributes, width and height, like:
img {
width: 100%;
height: 50%;
}
Although it will usually work if you only have either width or height, your situation is probably a bit different in that you are using percentages to deal with the image width and height.
Just add a class or id to the image and set it to width:100% and height:100%. Keep in mind that it will always be a 100% of the parent div in this case. Here's a very simple fiddle for you

How can I make div container with 3 images auto resizable?

I am trying to achieve similar effect as is on this page: http://ketrawars.com
When you try to resize a browser window, all images resize along with it. I can get that working if my div contains one image to which I set width 100%. However, I have a problem when I need to put 3 images one next to another.
My code:
<div class="content">
<img src="images/main_01.png" alt="" />
</div>
<div class="content">
<img src="images/main_02.png" alt="" />
<img src="images/main_03.png" alt="" />
<img src="images/main_04.png" alt="" />
</div>
CSS:
.content {
/* Set rules to fill background */
min-height: 100%;
min-width: 1024px;
/* Set up proportionate scaling */
width: 100%;
height: auto;
/* Set up positioning */
position: relative;
top: 0;
left: 0;
}
This is what it does:
And this is what is desired:
With the option to write text on the middle image (second one).
If you have three equally sized images, then set each of their widths to 32%:
.content img {
width:32%;
}
img elements are displayed as inline, by default. This means that the browser will add inline space between them, causing line breaks- you must subtract a percentage or two to compensate for this space.
I recommend displaying the images as blocks and then floating them to remove the inline space.
.content img {
display:block;
margin:0;
padding:0;
float:left;
width:33%;
}
If your images aren't equally sized, simply set their percentages so that all of the elements' widths add to 100.
Another good way to ensure that things will resize with the screen to use viewport units: vw and vh. They're defined as 1/100 the width and height of the viewport, respectively. Only Gecko based browsers will update them dynamically, however.
Codepen

Does every div needs a set height?

I'm stressing out because of a mindbreaker and I'm probably missing some essential, but easy thing.. And although I've done this many times before.. it's going wrong now.
So I'm creating a web app and always my starting point is
html, body {
height:100%;
width:100%;
}
And some of my inner elements have a set height in percentages and some in pixels.
However, to have some structure in my code, I'm setting up div's without a set height. Let's set up the following situation.
HTML
<div class="wrapper">
<div class="thisIsAStructureItem">
<div class="innerElement">
And just some untagged piece of text
</div>
</div>
</div>
CSS
.wrapper {
height:100%;
width:100%;
}
.thisIsAStructureItem {
/* nothing, not even height */
}
.innerElement {
height: 17.5%;
}
But in any editor or browser, because I haven't set a specific (%/px) height on the second element, it shows up as 0px, including all the inner elements.
So stupid as this might be.. What am I doing wrong?
UPDATE: See this JSFiddle
The situation makes it appear a set height is necessary, therefor so my title. Feel free to adjust to something more suitable
The situation above is a replica of a to-build-situation and using exact pixels is (at that above part) not an option. Please don't advice 'use X pixels'.
Original: http://jsfiddle.net/o0Lfyt0m
Updated: http://jsfiddle.net/o0Lfyt0m/1/ (from code sample below)
The innerElement is trying to display as 17.5% as tall as the parent element. The problem is that the parent element does not have a defined height. As a fall back to calculating 17.5% of undefined, the div's height is essentially defaulting to "auto" and assuming the height of it's content, which is based on the size of the font, line-height, padding etc.
Edit: A nice feature of CSS is that an elements styles can be inherited from it's parents. You can add a structure class which will inhert the height from it's parent element, which seems to be your intent.
You could even add this class to the body element, since it's height and width are identical to html... just not certain if the HTML element can be styled in all browsers, so I didn't do that.
html, body {
height: 100%;
width: 100%;
}
.wrapper {
height: 100%;
width: 100%;
}
.struct {
height: inherit;
width: inherit;
}
.innerElement {
height: 17.5%;
}
<div class="wrapper">
<div class="struct"> <!-- .struct inherits height/width from .wrapper -->
<div class="innerElement"> <!-- height calculated based on .wrapper -->
And just some untagged piece of text
</div>
</div>
</div>
Yes, you need to set the height 100% for that div too. Otherwise it's height is unknown and will not be able to take exactly the 100% height and innerElement height is not calculated accordingly.
To make sure, you must use the height 100% for that div too.
.wrapper {
height:100%;
width:100%;
}
.thisIsAStructureItem {
height: 100%;
}
.innerElement {
height: 17.5%;/* calc from it's parent div height i.e. thisIsAStructureItem*/
}
You are, in effect, asking the browser to calculate a height from an undefined value. Since that would equal a null-value, the result is that the browser does nothing.

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. 256x256, 1024x768, 500x400, 205x246, etc.) as 64x64. 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:
<img src="Runtime Path to photo" border="1" height="64" width="64">
Don't set height AND width. Use one or the other and the correct aspect ratio will be maintained.
.widthSet {
max-width: 64px;
}
.heightSet {
max-height: 64px;
}
<img src="https://placeimg.com/200/500/any/grayscale" />
<img src="https://placeimg.com/200/500/any/grayscale" width="64" />
<img src="https://placeimg.com/200/500/any/grayscale" height="64" />
<img src="https://placeimg.com/200/500/any/grayscale" class="widthSet" />
<img src="https://placeimg.com/200/500/any/grayscale" class="heightSet" />
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;
}
<img src="https://picsum.photos/seed/stackoverflow/200/300" class="none" />
<img src="https://picsum.photos/seed/stackoverflow/200/300" class="fill" />
<img src="https://picsum.photos/seed/stackoverflow/200/300" class="cover" />
<img src="https://picsum.photos/seed/stackoverflow/200/300" class="contain" />
<img src="https://picsum.photos/seed/stackoverflow/200/300" class="scale-down" />
here is the sample one
div{
width: 200px;
height:200px;
border:solid
}
img{
width: 100%;
height: 100%;
object-fit: contain;
}
<div>
<img src="https://upload.wikimedia.org/wikipedia/meta/0/08/Wikipedia-logo-v2_1x.png">
</div>
Set width and height of the images to auto, but limit both max-width and max-height:
img {
max-width:64px;
max-height:64px;
width:auto;
height:auto;
}
Fiddle
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.
<img src="Runtime Path to photo"
style="border: 1px solid #000; max-width:64px; max-height:64px;">
Use object-fit: contain in css of html element img.
ex:
img {
...
object-fit: contain
...
}
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:
<div style="background:center no-repeat url(...);background-size:contain;width:...;height:..."></div>
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.
img {
width: 100%;
aspect-ratio: 16/9;
}
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 64x64 and set width: inherit to the image:
<div style="width: 64px; height: 64px;">
<img src="Runtime path" style="width: inherit" />
</div>
Try this:
<img src="Runtime Path to photo" border="1" height="64" width="64" object-fit="cover">
Adding object-fit="cover" will force the image to take up the space without losing the aspect ratio.
You can set aspect ratio
img {
width: 64px;
aspect-ratio: 1/1;
}
<img src="Runtime Path to photo" border="1">
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.
eg:
image {
width: 64px;
height: 64px;
}
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
.img {
max-height: 100%;
max-width: 100%;
object-fit: scale-down;
}
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{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
<div style="max-width:100px; margin: 1rem auto;">
<p>4:3</p>
<div class="img-frame img-frame-4by3">
<img src="http://placekitten.com/g/400/400" />
</div>
<br />
<p>16:9</p>
<div class="img-frame img-frame-16by9">
<img src="http://placekitten.com/g/400/400" />
</div>
<br />
<p>5:1</p>
<div class="img-frame img-frame-5by1">
<img src="http://placekitten.com/g/400/400" />
</div>
</div>
With css:
.img {
display:table-cell;
max-width:...px;
max-height:...px;
width:100%;
}
The poster is showing a dimension constrained by height in most cases he posted >>> (256x256, 1024x768, 500x400, 205x246, 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:
<img id="photo1" style="height:64px;width:auto;" src="photo.jpg" height="64" />
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.

How can I resize an image to a percentage of itself with CSS?

I am trying to resize an image 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!
I have 2 methods for you.
Method 1.
This method resize image only visual not it actual dimensions in DOM, and visual state after resize centered in middle of original size.
img {
transform: scale(0.5);
}
<img src="https://via.placeholder.com/300x200" />
Browser support note: browsers statistics showed inline in css.
Method 2.
#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%;
}
<div id="wrap">
<img class="fake" src="https://via.placeholder.com/300x200" />
<div id="img_wrap">
<img class="normal" src="https://via.placeholder.com/300x200/cccccc" />
</div>
</div>
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:
#wrap and #wrap img.fake have flow
#wrap has overflow: hidden so that its dimensions are identical to inner image (img.fake)
img.fake is the only element inside #wrap without absolute positioning so that it doesn't break the second step
#img_wrap has absolute positioning inside #wrap and extends in size to the entire element (#wrap)
The result of the fourth step is that #img_wrap has the same dimensions as the image.
By setting width: 50% on img.normal, its size is 50% of #img_wrap, and therefore 50% of the original image size.
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.
span {
display: inline-block;
}
img {
width: 50%;
}
<span>
<img src="https://via.placeholder.com/300x200"/>
</span>
Edit: As mentioned by trojan, you can also take advantage of the newly introduced CSS3 intrinsic & extrinsic sizing module:
figure {
width: intrinsic;
}
img {
width: 50%;
}
<figure>
<img src="https://via.placeholder.com/300x200" />
</figure>
However, not all popular browser versions support it at the time of writing.
Scale the image:
img {
transform: scale(0.5);
}
<img src="https://via.placeholder.com/300x200" />
Another solution is to use:
<img srcset="example.png 2x">
It won't validate because the src attribute is required, but it works (except on any version of IE because srcset is not supported).
This is a very old thread but I found it while searching for a simple solution to display retina (high res) screen capture on standard resolution display.
So there is an HTML only solution for modern browsers :
<img srcset="image.jpg 100w" sizes="50px" src="image.jpg"/>
This is telling the browser that the image is twice the dimension of it intended display size. The value are proportional and do not need to reflect the actual size of the image. One can use 2w 1px as well to achieve the same effect. The src attribute is only used by legacy browsers.
The nice effect of it is that it display the same size on retina or standard display, shrinking on the latter.
This actually is possible, and I discovered how quite by accident while designing my first large-scale responsive design site.
The overflow:hidden gives the wrapper height and width, despite the floating contents, without using the clearfix hack. You can then position your content using margins. You can even make the wrapper div an inline-block.
.wrapper {
position: relative;
overflow: hidden;
}
.box {
float: left; /* Note: 'float:right' would work too */
}
.box>img {
width: 50%;
}
<div class="wrapper">
<div class="box">
<img src="https://via.placeholder.com/300x200" alt="">
</div>
</div>
function shrinkImage(idOrClass, className, percentShrinkage){
'use strict';
$(idOrClass+className).each(function(){
var shrunkenWidth=this.naturalWidth;
var shrunkenHeight=this.naturalHeight;
$(this).height(shrunkenWidth*percentShrinkage);
$(this).height(shrunkenHeight*percentShrinkage);
});
};
$(document).ready(function(){
'use strict';
shrinkImage(".","anyClass",.5); //CHANGE THE VALUES HERE ONLY.
});
This solution uses js and jquery and resizes based only on the image properties and not on the parent. It can resize a single image or a group based using class and id parameters.
for more, go here: https://gist.github.com/jennyvallon/eca68dc78c3f257c5df5
I think you are right, it's just not possible with pure CSS as far as I know (not cross-browser I mean).
Ok I didn't like my answer very much so I puzzled a little. I might have found an interesting idea which could help out.. maybe it IS possible after all (although not the prettiest thing ever):
Tested and working in Chrome, FF and IE 8&9. It doesn't work in IE7.
#img_wrap {
display: inline-block;
position: relative;
}
#rescaled_img_wrap {
width: 50%;
}
#original_img {
display: none;
}
#rescaled_img {
width: 100%;
height: 100%;
}
<div id="img_wrap">
<img id="original_img" src="https://via.placeholder.com/300x200" />
<div id="rescaled_img_wrap">
<img id="rescaled_img" src="https://via.placeholder.com/300x200/dddddd" />
</div>
</div>
This is a not-hard approach:
div {
position: absolute;
}
img,
div {
width: ##%;
height: ##%;
}
<div>
<img src="https://via.placeholder.com/300x200" />
</div>
Although it does not answer the question directly, one way to scale images is relative to the size (especially width) of the viewport, which is mostly the use case for responsive design. No wrapper elements needed.
img {
width: 50vw;
}
<img src="https://via.placeholder.com/300x200" />