Maintain the aspect ratio of an image using CSS and flexbox styling

I have a gallery of images that looks great on a full-size PC screen. However, when I resize it for viewing on a phone, the aspect ratio is not maintained and the images only stretch in width.

Currently, this is how it appears: https://gyazo.com/a1f605bb410865579025644b0a267adf

Additionally, you may notice that at certain points, the gallery transitions from showing one image to two images briefly before settling back to one image permanently. How can I resolve this issue?

This is the CSS code being used:

    #images{
        display: flex;
        flex-wrap: wrap;
    }

    .image{
        display: flex;
        flex: 1;
        margin: 5px;
        min-width: 250px;
        min-height: 187.5px;
        object-fit: contain;

    }

    .image > img{
        flex: 1;
    }

And here is the HTML code:

<div id="images">

            <div class="image">
                <img src="f1.jpg">
            </div>
            <div class="image">
                <img src="f2.jpg">
            </div>
            <div class="image">
                <img src="f3.jpg">
            </div>
            <div class="image">
                <img src="f1.jpg">
            </div>

            //the above structure continues
            //it's currently temporary and will be replaced with a loop.

</div>

Answer №1

If you don't have specific requirements in mind, I recommend using Masonry:

This JavaScript grid layout library optimally positions elements based on available vertical space, similar to a mason fitting stones into a wall. You've probably encountered it frequently across the Internet.

It works well when paired with imagesLoaded for a lightweight and versatile solution.

There are various ways to implement Masonry, but here's one that I personally prefer:

All of my comments can be found within the code snippet below:

body {
  background: #131418;
}

/* Step 1: Resetting some default styles */

* {
  margin: 0 auto;
  padding: 0;
  max-width: 100%;
}

/* Step 2: Centering content inside the grid and creating adequate spacing around it by setting a device-based max-width and margin */

.grid {
  text-align: center;
  max-width: 95vw;
  margin: 2.5vw auto;
}

/* Step 3: Setting the gap between grid items. Remember that the total gap between two items will be double what is set due to individual padding. Also, include box-sizing:border-box to ensure padding doesn't affect the total width of the item */

.grid-item {
  padding: 5px;
  box-sizing: border-box;
}

/* Step 4: Adding responsive media queries to make the entire grid adjust with different screen sizes */

@media (min-width: 500px) {
  .grid-item {
    width: 50%;
  }
}

@media (min-width: 1000px) {
  .grid-item {
    width: 33.333%;
  }
}

@media (min-width: 1700px) {
  .grid-item {
    width: 25%;
  }
}

@media (min-width: 2100px) {
  .grid-item {
    width: 20%;
  }
}
<!-- Made possible by the excellent work of David DeSandro @ https://masonry.desandro.com -->

<!-- Part 1: Including the necessary scripts -->

<!-- Step 1: Begin by loading jQuery. While not mandatory for Masonry, jQuery simplifies tasks -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Step 2: Next, load imagesLoaded. This ensures images are only displayed once fully loaded -->
<script src="https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js"></script>

<!-- Step 3: Load Masonry itself -->
<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>


<!-- Part 2: Creating the grid -->


<!-- Step 1: Start with the main grid wrapper-->
<div class="grid">

  <!-- Step 2: Add individual grid items--->

  <div class="grid-item">
    <img src="https://s-media-cache-ak0.pinimg.com/736x/00/37/03/0037037f1590875493f413c1fdbd52b1--cool-beards-inspiring-photography.jpg" />
  </div>

  <div class="grid-item">
    <img src="https://s-media-cache-ak0.pinimg.com/736x/cd/90/d9/cd90d9de63fa2c8e5c5e7117e27b5c18--gritty-portrait-photography-studio-photography.jpg">
  </div>

  <!-- Step 3: Repeat for additional items...--->
  <div class="grid-item">
    <img src="https://1.bp.blogspot.com/-9QM7ciGXRkQ/V1hsB-wNLBI/AAAAAAAAMoA/eYbSHs00PTAjrI4QAmvYAIGCUe1AuRAnwCLcB/s1600/bryan_cranston_0095.jpg">
  </div>

  <div class="grid-item">
    <img src="http://webneel.com/sites/default/files/images/project/best-portrait-photography-regina-pagles%20(10).jpg" />
  </div>

  <div class="grid-item">
    <img src="https://s-media-cache-ak0.pinimg.com/736x/dd/45/96/dd4596b601062eb491ea9bb8e3a78062--two-faces-baby-faces.jpg" />
  </div>

  <div class="grid-item">
    <img src="http://www.marklobo.com.au/news/wp-content/uploads/2013/03/Melbourne_Portrait_Photographer_Mark_Lobo-Cowboy.jpg" />
  </div>

  <div class="grid-item">
    <img src="https://format-com-cld-res.cloudinary.com/image/private/s--PcYqe7Zw--/c_limit,g_center,h_65535,w_960/a_auto,fl_keep_iptc.progressive,q_95/145054-8576001-Rob-Green-by-Zuzana-Breznanikova_7725_b_w.jpg" />
  </div>

  <div class="grid-item">
    <img src="http://www.iefimerida.gr/sites/default/files/janbanning11.jpg" />
  </div>

  <div class="grid-item">
    <img src="https://s-media-cache-ak0.pinimg.com/736x/66/bb/e7/66bbe7acc0d64da627afef440a29714b--portrait-photos-female-portrait.jpg" />
  </div>

  <div class="grid-item">
    <img src="https://s-media-cache-ak0.pinimg.com/736x/25/34/b6/2534b6c18c659546463f13b2dc62d4ce--natural-portraits-female-portraits.jpg" />
  </div>

  <div class="grid-item">
    <img src="https://s-media-cache-ak0.pinimg.com/originals/8d/67/12/8d671230ced871df8428b571ed6ec192.jpg" />
  </div>

</div>

<!-- Part 3: The script execution -->

<!-- Now that everything is loaded, create a script to trigger Masonry on $grid upon image completion. Note that this essentially says: "if all images are loaded, trigger Masonry on $grid." -->
<script>
  $(".grid").imagesLoaded(function() {
    $(".grid").masonry({
      itemSelector: ".grid-item"
    });
  });
</script>

Answer №2

I've recently come across a useful CSS property called object-fit

It offers various options including:

  • contain
  • fill
  • cover
  • none
  • scale-down

This property is user-friendly and helps to maintain the image ratio

For more information, check out the documentation HERE

Answer №3

UPDATE - An example has been included.

#images {
  display: flex;
  flex-wrap: wrap;
}

.image {
  flex: 1;
}

.image img {
  width: 100%;
  height: auto;
}
<div id="images">
  <div class="image">
    <img src="https://i.guim.co.uk/img/media/4f48e55216fe5c09963e6cac4ec2530cc08a4e36/0_0_600_600/master/600.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=add90ae66a8a0c9b35606346845539f9">
  </div>
  <div class="image">
    <img src="https://i.guim.co.uk/img/media/4f48e55216fe5c09963e6cac4ec2530cc08a4e36/0_0_600_600/master/600.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=add90ae66a8a0c9b35606346845539f9">
  </div>
  <div class="image">
    <img src="https://i.guim.co.uk/img/media/4f48e55216fe5c09963e6cac4ec2530cc08a4e36/0_0_600_600/master/600.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=add90ae66a8a0c9b35606346845539f9">
  </div>
  <div class="image">
    <img src="https://i.guim.co.uk/img/media/4f48e55216fe5c09963e6cac4ec2530cc08a4e36/0_0_600_600/master/600.jpg?w=300&q=55&auto=format&usm=12&fit=max&s=add90ae66a8a0c9b35606346845539f9">
  </div>

</div>

To maintain the image aspect ratio, you can set width:100% and height:auto. This will ensure the image adjusts to the container width while preserving the aspect ratio.

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

Customize your Bootstrap 4 navbar to align on the right with a button that remains visible on mobile devices

I'm working on setting up a navbar with three elements. I want to have a left-aligned brand, a group of right-aligned links that will collapse on smaller screens, and an additional button that stays visible at all times. To achieve the alignment of t ...

Ways to position every additional post alongside one another?

I'm currently working on my blog and I want new posts to be displayed next to each other, rather than stacked on top of one another. I have these cards set up, but they keep stacking underneath each other. If you need more of my code to help me out, p ...

Creating a CSS grid layout with a scrollbar positioned on the left side and content filling from left to right

How can I move the scrollbar to the left while keeping ng-repeat population from left to right? I'm using an ng-repeat to fill a grid that is 3 by X (Width by height). By default, the scroll bar appears on the right side. I want to position it on the ...

Using Jquery to create a slideshow with a div that is set to absolute

<!DOCTYPE html> <html> <head> <script> $(document).ready(function(){ $("#flip").click(function(){ $("#panel").slideDown("slow"); }); }); ...

Ways to retrieve a class list of a tag located within a div by clicking on the div, rather than the tag itself

I have 2 divs with an a tag and an i tag enclosed within them. I am using an onclick function, but it does not require writing the function itself. You can use something like getting elements on click of this item and then finding a certain class within th ...

Footer not sticking to the bottom of the page with Material UI

View Page Screenshot My challenge is with the Footer using AppBar when there is no content. It doesn't properly go to the end of the page, only to the end of the content. I want it to stick to the bottom of the page if the content doesn't reach ...

Top section of a table repaired

It seems that the position fixed attribute is not working as expected in this scenario. I might be missing something. I'm trying to keep the input boxes in the first row frozen when scrolling, but none of the solutions I've found seem to be effe ...

Instructions for creating a Google Maps overlay that hovers above the zoom bar

Let me share my workaround for creating an overlay and dealing with z-index issues when using Google Maps API. The problem arises when dragging the map and the overlay ends up behind control elements like the zoom bar. No matter how much I adjust the z-ind ...

Is the initial carousel element failing to set height to 100% upon loading?

If you take a look here, upon loading the page you will notice a DIV at the top. It is labeled "content" with "content_container" wrapped around it and finally, "page" around that. Clicking the bottom left or right arrows reveals other DIVs with similar ta ...

Shift designated list item to the right with overflow handling

A current project involves working on a sidebar created in bootstrap, and I've encountered an issue. I can't seem to move a selected item to the right and have it flow over the nav div. I attempted to increase the z-index with no success. One su ...

Transferring the final space from a node containing a mixture of content to a separate

Having a multitude of HTML files generated by MS Word, my objective is to modify the contents in order to extract data and perform other tasks. In an HTML paragraph with mixed content, I have noticed that spaces after italicized or bold words also become ...

Applying the transform:scale property to the parent element causes the child element's dropdown menu to appear beneath a different row

When attempting to scale my row on hover, I encounter an issue with my dropdown menu. If the dropdown menu is open, it gets hidden under the next row. How can I ensure that it stays on top? I have tried using z-index, but it doesn't seem to help. The ...

Extracting Values from JSON Array using Form Input Text

After designing a form for my web application, I encountered a situation where some fields needed to be populated with values from a JSON array retrieved from the treatment table in the database. {"treatment":[ { "id" : 1, "name" : "Leg Training" }, ...

Unable to apply 3rd condition with ngClass into effect

I've been attempting to incorporate a third condition into my ngClass. Initially, I managed to get two classes working in my ngClass to change the row colors alternately. [ngClass]="{ totalrow:i%2 != 0, odd:i%2 == 0}" Now, I'm trying to introdu ...

Problem with Chrome Compatibility for Bootstrap Carousel

My webpage features a carousel implemented as a slider. It seems to be working fine in Firefox and mobile browsers, except for Chrome where it doesn't show up at all. I can't seem to figure out what's causing the issue. Here is the syntax I& ...

Display a pair of divs by utilizing the select option tag element alongside a submit button

Yesterday, I posted a similar question in a different format. Today, I am looking for the same question in a new format. Let me explain: I have several div elements on a page. When I choose an option from a dropdown menu and click submit, I want to disp ...

Prevent the display of HTML tags in ASP.NET

Looking for a way to prevent a specific HTML tag from being printed in my ASP.NET project view file, whether through a printer or to a PDF file. Are there any HTML or CSS attributes that can help achieve this? How should they be configured? I have alread ...

Arrange data into columns on a website

In my project, I'm exploring the challenge of creating a square 2 x 2 grid alongside a rectangular column on the right-hand side. While attempting to implement a grid system for the 2 x 2 layout, I encountered issues with the alignment of the rectang ...

HTML Code for Tracking Facebook Friends' Likes on a Page

I am looking to show the number of friends who have liked a page in HTML. Can someone please guide me on this? I am aware that we can get the page likes using a simple URL, but I specifically want to know how to retrieve the count of friends who liked a ...

Does anyone know if it's feasible to return a value from PHP to an HTML form without relying on JavaScript?

Currently, I am in the process of learning how to create a basic web form. My goal is to develop an HTML web form that sends a number to PHP and then displays the number in another text field without refreshing the page. After doing some research online, ...