简体   繁体   中英

scale image to fit its parent object proportionally

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 ap, 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.

Adapt image to fit parent container (of unknown size) without stretching image


Instead of messing with JS, let CSS do the job!

  • Set your image to 100%; height and width;
  • Replace your image's src with a transparent pixel and set it's background to the actual src .
  • Use CSS's background-size on your (now) full-sized image:

contain (image will cover the parent completely)
cover (image will respect image proportions instead)

Example using 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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM