Reputation: 2427
I realise this has been asked many times under many guises, but most solutions seem to not care about the resulting image height, or only scale in one direction. This:
min-width: 100%;
height: auto;
isn't a solution.
I'm trying to fit an image to the height and width so that it can be dynamically injected into a number of places in different systems and sites, so I don't necessarily know what the parent object is going to be - might be a div with or without overflow set, or a p, or the body - or its dimensions; The parent container mustn't change size just by injecting my image/script .. jQuery is NOT available.
I can't see how the css3 background technique would work.
Proportional scaling is as easy as using a ratio:
<img onload="scale(this)" src="screenshot.png">
<script type="text/javascript">
function scale(img){
var p = img.parentNode,
x = p.offsetWidth,
y = p.offsetHeight,
w = img.naturalWidth,
h = img.naturalHeight;
ratio = h / w;
if (h >= y) {
h = y;
w = h / ratio;
img.style.width = w + "px";
img.style.height = h + "px";
} else if(w >= x) { //} && ratio <= 1){
w = x;
h = w * ratio;
img.style.width = w + "px";
img.style.height = h + "px";
}
}
</script>
but this only scales in one plane - I need it to continue to scale both width and height until it fits into the parent container space neatly in both dimensions. If the image is smaller than the parent container, it should scale UP to fill proportionally.
Upvotes: 0
Views: 1894
Reputation: 595
I used this code to fit a video to its parent:
var parent = vid.parentNode,
vw = vid.videoWidth,
vh = vid.videoHeight,
vr = vh / vw, // video ratio
pw = parent.offsetWidth,
ph = parent.offsetHeight,
pr = ph / pw; // parent ratio
if(pr > vr) {
vid.style.width = 'unset';
vid.style.height = `${ph}px`;
} else {
vid.style.height = 'unset';
vid.style.width = `${pw}px`;
}
Upvotes: 0
Reputation: 206151
100%;
height and width;src
with a transparent pixel and set it's background to the actual src
. background-size
on your (now) full-sized image:contain
(image will cover the parent completely)
cover
(image will respect image proportions instead)
contain
function scale( img ) {
if(img.isScaled) return;
img.style.background="no-repeat url("+ img.src +") 50%";
img.style.backgroundSize="contain"; // Use "contain", "cover" or a % value
img.style.width="100%";
img.style.height="100%";
img.isScaled=true; // Prevent triggering another onload on src change
img.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
}
<div style="width:300px; height:300px; background:#000; margin:10px;">
<img onload="scale(this);" src="//placehold.it/1200x600/f0f">
</div>
<div style="width:300px; height:300px; background:#000; margin:10px;">
<img onload="scale(this);" src="//placehold.it/400x600/cf5">
</div>
Tested in: FF, CH, E, IE(11), SA
NB: The transparent pixel data is used solely to prevent the browser's Missing Iimage Icon that would be otherwise caused by doing img.src = "";
http://caniuse.com/#search=background-size
Upvotes: 3