A guide to efficiently filling multiple rows of images with different heights while preserving their aspect ratio

I am facing a design challenge that I believe can be solved using CSS, although it might require some Javascript.

My issue involves a gallery of images with varying sizes and proportions. I would like to achieve the following:

  1. Distribute the images in more rows
  2. Adjust their sizes and row distribution based on a maximum height and the screen size they are viewed on
  3. Fill an entire row with images while maintaining fixed margins between them

Below is a sketch illustrating what I am aiming for:

https://i.sstatic.net/bjZo7.jpg

As shown in the sketch, the second row has a greater height than the first in order to accommodate larger images, which is acceptable given the constraints.

Despite my efforts, I have not been able to achieve this desired layout. The closest I got was to distribute the images evenly with fixed margins but at the expense of their aspect ratios being distorted (I suspect the issue lies with min-width and max-height). Why can't I set a max-height and adjust the width accordingly?

Here is a snippet of my HTML code:

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

And here is how I styled it using 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;
}

While I successfully distributed the images evenly with proper spacing using justify-content: space-between, I am not satisfied with this solution.

Do you have any suggestions or ideas on how I can achieve the desired layout?

Answer №1

Hopefully this is the solution you've been searching for - check out this CodePen

Please take note that the CSS property object-fit may have compatibility issues with certain browsers like IE11. Feel free to inform me if this resolves your issue.

Answer №2

I encountered a similar issue where I needed to adjust the layout of images within a div using CSS and JavaScript.

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

To ensure proper alignment, I utilized JS functions like loadCheck() to wait for image loading completion, adjustAll() to organize images by top position, and resize() to resize images to fit the row perfectly.

Interestingly, running the resize() function twice was necessary for accurate results, but it ultimately resolved the display issue.


// Functions to resize images
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];
}

// Adjust all images based on their top position
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]);
        }
    }
}

// Check for completion of image loading
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);

In addition to these functions, I implemented a check for window resizing to automatically run adjustAll() for responsive design adjustment.

NOTE: It's important to consider adjustments for margins or padding in the code to ensure correct alignment.

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

BEFORE

https://i.sstatic.net/JcvcY.jpg

AFTER https://i.sstatic.net/TdiCw.jpg

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Choose a node from descendants based on its attribute

I am working with an interface that switches between displaying different div elements. Each div element has their children arranged differently, and when the switch happens, I need to access a specific child node of the newly displayed div. However, I fin ...

Why does Thymeleaf th:field treat null differently with input text than with radio buttons?

I recently started using Thymeleaf and the documentation has been very helpful so far. However, I've been stuck on a form for hours despite doing a lot of research! I am trying to preload test data in an HTML form (the actual data will come from a dat ...

You need to click the form submit image twice in order to make it work

Struggling to get a standard opt-in form to work with an image submit button. The script works fine with a regular submit button, but the image button requires two clicks initially and then one click after unless the page is refreshed. I believe there mig ...

What is the best way to transmit a response from PHP to Ajax?

A JavaScript function is used here that utilizes the POST method to send form data to PHP. The PHP script then checks this data in a database to verify its authenticity. However, there seems to be confusion on how to convey the response from PHP back to Ja ...

Including a .css file in ejs

I'm currently developing an application using Node.js (express) with EJS, and I'm facing an issue while including a .css file in it. When I tried the same setup as a standalone HTML-CSS project, it worked perfectly fine. How can I include the CSS ...

Lists within lists and the use of percentages

There is a common belief that separating design and functionality is beneficial. Let's focus on the separation between HTML and CSS, specifically when organizing a menu hierarchy. The issue with nested <ol>, <ul>, and <li> elements ...

The front end button stubbornly refuses to comply and redirect to another page

I am having trouble getting my button element to redirect my page to another page. I have tried using an onclick function inside the button tag with window.location.href, as well as creating a separate function for the redirect, but nothing seems to be wor ...

Utilizing Angular 9's inherent Ng directives to validate input components within child elements

In my current setup, I have a text control input component that serves as the input field for my form. This component is reused for various types of input data such as Name, Email, Password, etc. The component has been configured to accept properties like ...

React-select: issue with maintaining selected option on input

Hello everyone, I am new to React and seeking some assistance in reviewing my code. I have a component called Bucket that contains multiple challenges as separate components. Here is a simplified version of the code: class CLL_Bucket extends Component { ...

What is the reason behind the observation of executed javascript upon receiving a JSON response from the server?

My current knowledge of HTTP involves web browsers sending mainly GET or POST requests, with the server responding accordingly. I am aware that servers can return a complete HTML document that is ready to be displayed in a web browser. Additionally, I un ...

Verify if the value in a textbox exceeds the number entered in an array of textboxes

My goal is to compare the value of a single text box, labeled as "totalmarkstoall", with multiple arrays of text boxes labeled as "marksscored". The JavaScript code below is set up to compare these values using a key up function. The issue I am facing is ...

How to open a new window in a separate desktop on macOS using Javascript

I am currently browsing my website on a Mac computer. I am interested in opening a new tab on the second desktop using Mission Control. Is this achievable? If so, could you please guide me on how to do it? After searching extensively online, I have been u ...

Ensuring that the bootstrap5 column extends all the way to the footer

Looking to display a specific email address mailbox for a project. The goal is to have the 'Mail Card List' scrollable instead of extending beyond the page. Tried using 'max-height:;' CSS, but it sets a fixed height. Seeking a variable ...

Decoding Encrypted HTML with Incorrect Formatting

After retrieving encoded HTML from the database, I decoded it in one section but noticed that the bold, italic, and other formatting were not displaying. Only plain text was showing. Here is my code: string a = da.GetLeftPanelData();//<-- in here Enco ...

Ionic - Landscape Mode Causing Alignment Distortion

I'm currently working on designing a grid-based image display for an Ionic Mobile App. One of the main challenges I'm facing is adjusting the heights of the images based on the screen size. I want to set a maximum height for both portrait and lan ...

The CSS class is mistakenly being applied to the entire page instead of just the specific div it was

Here is the HTML code I am working with: <!DOCTYPE html> <head> <title></title> {% load staticfiles %} <link rel="stylesheet" type="text/css" href="{% static 'portfolio/mystyle.css' %}" /> <link rel="styl ...

Creating a two-column grid layout using Bootstrap 4 is a simple and efficient process. Let's see how

I've been struggling to get this to display side by side in a two-column grid. Even after following Bootstrap tutorials, I can't seem to make it work. Check out the code below: <div class="row"> <div class="col-md-8 ...

Stop manipulating links with jquery mobile to maintain original behavior

I have a situation where I am listing WordPress posts, and when I click on a title, jQuery is loading the single post page for me via ajax. However, I don't want this behavior - I just want the link to act normally. I have tried using the following co ...

When the onclick function is triggered, two or more characters will be displayed

Functionality: To input name and email, users must click on the virtual keyboard displayed on the screen. Characters entered will be shown in the input box. Implementation: The HTML keyboard interface and associated script have been developed successful ...

Tips for accurately aligning a relative p tag within a td

Description: I am trying to prevent text overflow in a table cell and position the text underneath a header without wrapping it under an image. I have tried setting a static width for the image and adjusting the left property, but it is not working as expe ...