简体   繁体   中英

How to completely fill several rows of images by varying their height and maintaining their aspect-ratio

I have a design problem I'd like to solve via CSS, but I have the feeling It can be done just with a javascript.

I have a gallery of images of different sizes and proportions. I'd like them to:

  1. distribute in more rows
  2. adjust their sizes and row distribution according to a given maximum height and to the monitor size on which they are viewed
  3. fill in all the space of a single row, with fixed margins between them

Here's a sketch of what I'd like to accomplish

在此处输入图像描述

As you can see, the second row is higher than the first, in order to fill in all the space with the larger images, and I'm ok with that (it's the only way this can be done).

I didn't manage to achieve this. The best I could do is to equally distribute the images with fixed margins BUT with aspect-ratio totally messed up (I know the problem here is min-width and max-height … why can't I give a max-height and adjust width consequentially?)

HTML

<div class="img-blocco">
    <img src=“1.jpg” /> <img src=“2.jpg” /> … <img src=“n.jpg” /> 
</div>

CSS

.img-blocco {
    height: 100%;
    width: 90%;
    padding: 0 5%;
    overflow: hidden;
    position: relative;
    display:flex;
    flex-wrap: wrap;
}

.img-blocco img {
    margin: 0 5px 10px;
    min-width:200px;
    max-height:300px;
    flex-grow:1;
}

I obviously managed to equally distribute my images with their correct aspect-ratio spacing them with justify-content: space-between , but I don't like this solution at all.

Any ideas?

Hope this is what you are looking - Pen .

Note that the CSS property object-fit has issues with browser support in ie11 . Let me know whether this helps.

I had a similar issue. I have a div holding all the images with the following CSS

#ImageHolder {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-content: flex-end;
    align-items: center;
    justify-content: left;
}
.thumbnail {
    height: 25vh;
    margin: 0.5vh 0.25vw 0.25vw 0.5vh;
    user-select: none;
}

I then use the following JS functions to wait until the items are all loaded loadCheck() , go through and find images with the same top position adjustAll() , then resize it to fill the entire row with resize()

For some reason, I have to run resize twice to get it to fit correctly, but it does work.


function resize(workinglist){
    var vw=window.innerWidth/100;
    var maxWidth=ImageHolder.getBoundingClientRect().width-(workinglist.length * 0.5 * vw);
    var totalWidth=0;
    for (x in workinglist){
        totalWidth+=workinglist[x].getBoundingClientRect().width
    }
    var ratio=2-(totalWidth/maxWidth);
    for (x in workinglist){
        workinglist[x].style.height=(workinglist[x].getBoundingClientRect().height*ratio)+"px";
    }
    var totalWidth=0;
    for (x in workinglist){
        totalWidth+=workinglist[x].getBoundingClientRect().width
    }
    return [totalWidth,maxWidth,ImageHolder.getBoundingClientRect().width,ratio];
}



function adjustAll(){
    var workinglist=[];
    var imgs=Array.from(ImageHolder.children);
    for (place in imgs) imgs[place].style.height="";
    var imgTop=imgs[0].getBoundingClientRect().top;
    for (place in imgs){
        if (imgs[place].getBoundingClientRect().top==imgTop){
            workinglist.push(imgs[place]);
        }else{
            resize(workinglist);
            resize(workinglist);
            workinglist=[];
            imgTop=imgs[place].getBoundingClientRect().top;
            workinglist.push(imgs[place]);
        }
    }
}

function loadCheck(){
     var imgs=Array.from(ImageHolder.children);
     for (place in imgs){
         if (! imgs[place].complete){
             console.log("Not Loaded yet");
             return false;
         }
     }
     adjustAll();
     clearInterval(lc);
     console.log("I resized everyone");
}

ls=setInterval(loadcheck,100);

I also add a function to check for window resize and run adjustAll() when that happens.

NOTE you will need to adjust the effects of the margins in your code. If you do padding, then you can remove the adjustments for margins in the resize function .

var maxWidth=ImageHolder.getBoundingClientRect().width-(workinglist.length * 0.5 * vw);

BEFORE

调整大小前的图像

AFTER调整大小后的图像

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