简体   繁体   中英

Resizing images of different aspect ratios to fit a div without stretching it

I'm making a portfolio website and I am trying to make a simple image browser. I have a container div with size relative to the size of the browser window. I want that div to be able to contain images of different aspect ratios and a caption of fixed height and the width relative to the width of the image. I don't want the div to stretch to contain the images, I want to resize the image (you can see what I mean in the picture below).

illustration of the problem here

I was trying to use javascript to calculate the size of the image, but failed, because I couldn't calculate the element's size before it is actually loaded. This is how I tried to do it (not thinking about the titlebar):

var divAspectRatio = containerDiv.offsetHeight/containerDiv.offsetWidth;
var imageAspectRatio = image.offsetHeight/image.offsetWidth;
if(divAspectRatio>imageAspectRatio){
  image.style.height = content_in.offsetHeight;
}else{
  image.style.width = content_in.offsetWidth;
}
captionDiv.style.width = image.offsetWidth;

How do I make it work?

Try using this css element:

object-fit: cover

This way, your image will get resized to fit the containing box!

If your background image is in a div element, add this to your css, inside the div block: background-size: cover;

If it's in an img element, add this to your css, inside the img block: object-fit: cover;

The desired layout needs some calculation as the placing of an image that has aspect ratio bigger than the aspect ratio of the container differs from one that doesn't. Also to note is that the caption area is required to be only as wide as the displayed image but has a fixed height.

The imgs are wrapped in an 'innerdiv' which will also contain the caption. On loading the image's aspect ratio is found and stored as a CSS variable. Other CSS variables are set up in advance - see the head of this snippet for those that can be chosen. Remaining calculations are done in CSS.

 window.onload = function () { const imgs = document.querySelectorAll('.container.innerdiv.img'); imgs.forEach(img => { img.parentElement.style.setProperty('--imgratio', img.naturalWidth / img.naturalHeight); img.parentElement.classList.add(( (img.naturalWidth / img.naturalHeight) > getComputedStyle(img).getPropertyValue("--containerratio") )? 'wider': 'thinner'); }); }
 * { padding: 0; margin: 0; }.container { /* SET THE NEXT 4 VARIABLES TO WHAT YOU REQUIRE */ --unit: 1vmin; /* the basic unit - must be fixed eg vmin, px, ch not % */ --containerw: 40; /* width of a container in these units */ --containerratio: 1.5; /* the ratio of width to height */ --captionh: 4vmin; /* height of a caption including its units (which must be fixed eg vmin, px, em */ --containerh: calc(var(--containerw) / var(--containerratio)); display: inline-block; width: calc(var(--containerw) * var(--unit)); height: calc(var(--containerh) * var(--unit)); position: relative; border: solid; }.innerdiv { display: inline-block; position: absolute; top: 0; left: 0; }.innerdiv.thinner { width: calc(var(--imgratio) * ((var(--containerh) * var(--unit)) - var(--captionh))); height: 100%; left: 50%; transform: translateX(-50%); }.innerdiv.wider { width: 100%; height: calc((var(--containerw) / var(--imgratio)) * var(--unit) + var(--captionh)); top: 50%; transform: translateY(-50%); }.img { width: 100%; height: auto; }.caption { font-size: 2vmin; background-color: yellow; text-align: center; width: 100%; height: var(--captionh); position: absolute; top: calc(100% - var(--captionh)); left: 0; }
 <div class="container"> <div class="innerdiv"> <img class="img" src="https://picsum.photos/id/1016/200/300"> <div class="caption">CAPTION</div> </div> </div> <div class="container"> <div class="innerdiv"> <img class="img" src="https://picsum.photos/id/1016/500/200"> <div class="caption">CAPTION</div> </div> </div> <div class="container"> <div class="innerdiv"> <img class="img" src="https://picsum.photos/id/1016/300/300"> <div class="caption">CAPTION</div> </div> </div>

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