Designing a flexible and consistent grid system using only CSS to showcase any number of images, ensuring each tile seamlessly adjusts to the dimensions of the largest element

[edit : preamble]

Regardless of the nature of your response, please support your arguments with technical references from credible sources. Appreciate your help in advance.

[Question]

I am seeking to design a CSS grid layout that is responsive for images with varying numbers of elements while maintaining their original resolution and centering them in their cells. The largest image serves as the reference point, fitting exactly into its cell, and the grid adjusts responsively based on available space (creating new rows only when required).

While my current grid setup is satisfactory, it necessitates knowing the precise size of the largest square image to use it as the standard reference without any surrounding spaces.

It might be challenging to achieve this using pure CSS alone. I have been struggling with it and would appreciate any suggestions you can offer.

.gallery {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(auto, 100px));
  justify-items: center;
  align-items: center;
}

.gallery img {
  width: auto;
  height: auto;
  object-fit: scale-down;
  object-position: center center;
}
<div class="gallery">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
</div>

Having a flexible solution without relying on a hardcoded value like 100px would be highly beneficial.

Answer №1

Regrettably, your issue cannot be resolved using only css. As previously stated, the auto-fill property necessitates a fixed size.
Hence, I recommend incorporating a minimal amount of javascript and establishing a css variable.
Additionally, the example below addresses the issue of preventing "jumping" after calculating the image width:

window.onload = () => {
  /* Finding the widest image. */
  const largestImgWidth = [...document.querySelectorAll('.gallery img')].reduce( (prev, current) => prev = current.offsetWidth > prev ? current.offsetWidth : prev, 0);
  /* Setting the largestImgWidth in the css variable */
  document.querySelector('.gallery').style.setProperty('--largest-img-width', largestImgWidth + 'px')
}
.gallery {
  /* Initial col width */
  --largest-img-width: 0;
  display: grid;
  place-items: center;
  grid-gap: 1rem;
  grid-template-columns: repeat( auto-fill, minmax( var(--largest-img-width), 1fr) );
  /* Hide until the grid is formed */
  opacity: 0;
}

.gallery[style] {
  /* Display it after forming the grid */
  opacity: 1;
}
<div class="gallery">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
</div>

Answer №2

Improving the snippet slightly, but still limited to 100px

.gallery {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  justify-items: center;
  align-items: center;
}

.gallery img {
  width: auto;
  height: auto;
}
<div class="gallery">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
</div>

Masonry layout is not yet integrated into the grid system, but it's on its way. Once available, you can use the Masonry plug-in. More information here:

Alternatively, with JavaScript, you can use getBoundingClientRect to check the size of all images.

Answer №3

If you wish to maintain the same size for all images in the grid.

.gallery {
            display: grid;
              grid-gap: 1rem;
            grid-template-columns: repeat(auto-fill, minmax(auto, 100px));
            justify-items: center;
            align-items: center;
        }
            
        .gallery img {
            width: 100%; /* updated to 100% */
            height: 100%; /* updated to 100% */
            object-fit: fill; /* modified from scale-down */
            object-position: center center;
        }
<div class="gallery">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
</div>

Answer №4

If you want to set a CSS variable using JavaScript, you can simply assign the value directly within the style property.

const searchMaxWidth = () => {
  let mw = 0;
  document.querySelectorAll('.gallery img').forEach(el => {
    if (el.getBoundingClientRect().width > mw) mw = el.getBoundingClientRect().width;
  })
  console.log(mw);
  document.querySelector('.gallery').style.gridTemplateColumns = 'repeat(auto-fill, minmax(' + mw + 'px, 1fr))';
}
window.addEventListener('load', searchMaxWidth);
.gallery {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  justify-items: center;
  align-items: center;
}

.gallery img {
  width: auto;
  height: auto;
}
<div class="gallery">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
  <img src="https://picsum.photos/25">
  <img src="https://picsum.photos/50">
  <img src="https://picsum.photos/75">
  <img src="https://picsum.photos/100">
</div>

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

What is the best way to vertically align Bootstrap Columns to ensure they have consistent heights?

I'm currently in the process of building a website that features multiple images and content organized into columns using Bootstrap as the framework. I'm wondering if there's a way to automatically adjust all the columns to the height of th ...

Paged Content: Turning a Lengthy Text into a Book-Like Format

I have a unique idea for displaying text like a flipping book on a web page. Users can use arrow keys to navigate through the content, giving it an interactive and engaging feel. Instead of focusing solely on page transitions, I am looking into implementi ...

powerful enhancer separates the heading into a layout

I have an HTML div element that just isn't behaving right when I resize the screen. The title pretty much sums it up: <div class='serveMessage'><strong>Fun fact:</strong>&nbsp;over 1,259,468 American students fail ev ...

Eliminate repeated elements within the DOM

Are you looking to eliminate duplicate elements with the same classname (valid) from the DOM? Check out the example below: <div class="content"> <div class="test1"> <label class="valid">&nbsp;</label> <label class="v ...

Tips for transferring input values between two PHP pages

I need to save various input values in a MySQL database, such as first name, last name, phone number, and mobile number. With a select query, I can retrieve all the entries from the database and display them on a single webpage. When a user clicks on a sp ...

CSS selectors duplication can cause confusion and make code harder to maintain. SCSS

If we have style definitions like the following: .a.b { ... } .a.b.c { ... } Is there a method in SASS/SCSS to prevent duplication of the .a.b part? ...

Fade-in loader with centered placement on the full page

As a newcomer to programming, I wanted to implement a loader that displays a centered loading animation when the page loads or refreshes. The animation should gray out and fade the entire page until it fully loads. I've managed to get everything else ...

Display the div based on the choices made in both select elements

Image of code is currently not accessible on this device Apologies for the lack of visual aid, I have coded on a different device. I am looking for a way to make the div appear based on certain options selected from both dropdown menus. Any assistance wit ...

What are the steps to restrict a user from accessing a specific website?

In my Vue.js project, I've implemented a function that hides a specific menu item for users with insufficient permissions: <a :href="href" @click="navigate" v-if="hideMenuItem()"> // some code </a> hideMe ...

Centering the scroll bar with Flexbox

Is it possible to center the scroll bar of a flex box in the middle of the screen? Currently, when using the code below I am seeing the UI as shown below, with the scroll bar at the bottom of the container DIV https://i.sstatic.net/XakpC.png Instead, is ...

When you start scrolling down, the JavaScript menu will cleverly disappear, only to re

I am facing an issue with my menu, which is a normal block-displayed div. There is another div with annotation above it. I want the menu to stick to the top as fixed when scrolling down, but immediately hide itself. The goal is for the menu to appear when ...

Creating Uniform Column Heights with Bootstrap

Is there a way to ensure that all my Bootstrap columns are the same height? Currently, when one column has more content than another, the layout appears uneven. Here is an example on Fiddle that illustrates the issue: https://jsfiddle.net/jjq9gygr/ I at ...

Python Selenium Automation Loop

I want to create a script that can loop through a list of values for the .send_keys function. I have these values stored in an excel document and I plan to retrieve them using openpyxl in Python. Alternatively, I can define the list directly in Python if n ...

Using PHP, JavaScript is unable to hide <div> elements

I'm encountering an issue where the div I want to show when an error occurs is not hiding and showing properly using JavaScript. Here is a snippet of my code: <script> function hideerror() { var catdiv = document.getElementById(error); ...

How come I am unable to scroll beyond my parallax section unless I move the mouse first?

Currently, I am working on a webpage that includes a Parallax landing image. In order for the Parallax effect to function properly, the image has a greater height, requiring users to scroll down. This leads to the appearance of a second scrollbar specifica ...

What is the best way to place my website's logo in the top-left corner using html and css?

Hello everyone. I am currently working on customizing a website using an HTML and CSS template for a project, but I need to make some modifications. My main goal is to add the company logo to the header, specifically in the top-left corner, however, I&apo ...

Properly appears in Chrome, but experiences issues in Internet Explorer 11

The design of the website looks seamless in Chrome and Firefox, however, when I view it in Internet Explorer, I notice a significant gap on the right side of the first two pages. How can I fix this issue specifically for Internet Explorer? Should I use a m ...

Tips for creating dynamic animations in an opencart dropdown menu

Currently, I am in the process of enhancing my ecommerce website using OpenCart and I have been trying to incorporate a simple animation for the dropdown menu. However, despite applying the transition properties in the code snippet below, it seems that the ...

The Enchanted URL Folder Name

Spent two painstaking hours dealing with this issue. It's incredibly frustrating. Struggling to load css files in PHP pages when the URL contains a folder named "adsq" Comparing two identical pages, only differing in the folder name: One works perf ...

The CSS property for restricting white-space to nowrap is not functioning as

Having a div with multiple child divs floating left can be tricky. To prevent them from breaking, setting them to display:inline-block and white-space:nowrap seems like the solution. However, in some cases this may not work as expected. If your goal is to ...