1

After sorting through dozens of Flexbox questions on this website with no luck, I figure it's time to just ask.

I want a row of images where the row stretches the entire width of the window, each image is the same height, and all images maintain their original aspect ratios. As an example, I have:

ul {
  width: 100%;
  list-style-type: none;
  padding: 0;
  display: flex;
  align-items: stretch;
}

li {
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

img {
  max-height: 100%;
  max-width: 100%;
  object-fit: contain;
}
<ul>
  <li>
    <img src="https://dummyimage.com/1920x1080"/>
  </li>
  <li>
    <img src="https://dummyimage.com/1400x1000"/>
  </li>
  <li>
    <img src="https://dummyimage.com/500"/>
  </li>
</ul>

The question Maintain image aspect ratio when changing height is very similar, but the problem with those answers is that all the images are the same aspect ratio.

Antyos
  • 455
  • 5
  • 11
  • if the ratio for each image is known, you can do it. For random aspect ratio, it would be difficult (if not impossible) – Temani Afif Jun 20 '22 at 19:11
  • I could see how arbitrarily sized images could make this a pain. The ratio of each image is known, and the Flexbox does not wrap. – Antyos Jun 20 '22 at 19:53
  • I’m not clear why flex is involved. If you know the total width is 100vw then the height is 100vw divided by the sum of the aspect ratios, give or take any gaps required. Have I misunderstood the problem? – A Haworth Jun 20 '22 at 20:44
  • 1
    here is an example for **landscape** img of different size using js to do the calculation https://codepen.io/gc-nomade/pen/vYdwZNm (flex is here only involved to draw a row from li not in sizing img ) . You may inspire yourself from that codepen – G-Cyrillus Jun 20 '22 at 22:02
  • 1
    @G-Cyrillus consider adding it as an answer (I reopened the question since the duplicate is irrelevant) – Temani Afif Jun 20 '22 at 23:35
  • @TemaniAfif i answered and removed it cause your answer via js worked fine ;) – G-Cyrillus Jun 23 '22 at 12:23

2 Answers2

2

If the ratio is know do it like below. Note the use of a variable where you define the ratio of each image

ul {
  list-style-type: none;
  padding: 0;
  display: flex;
}

li {
  flex-grow: calc(var(--r));
  flex-basis: 0;
}

img {
  max-width: 100%;
}
<ul>
  <li style="--r: 1920/1080">
    <img src="https://dummyimage.com/1920x1080"/>
  </li>
  <li  style="--r: 1400/1000">
    <img src="https://dummyimage.com/1400x1000"/>
  </li>
  <li  style="--r: 500/500">
    <img src="https://dummyimage.com/500"/>
  </li>
</ul>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
0

I ended up combing @Temani Afif's and @G-Cyrillus' approaches to get:

let smoothImg = function () {
    const images = document.querySelectorAll("ul li img");
    for (image of images) {
        image.parentElement.style.flexGrow = image.offsetWidth/image.offsetHeight;
    }
};

window.onload = smoothImg;
window.onresize = smoothImg;
ul {
  list-style-type: none;
  padding: 0;
  display: flex;
}

li {
  flex-grow: 1;
  flex-basis: 0;
}

img {
  max-width: 100%;
}
<ul>
    <li>
        <img src="https://dummyimage.com/1920x1080" />
    </li>
    <li>
        <img src="https://dummyimage.com/1400x1000" />
    </li>
    <li>
        <img src="https://dummyimage.com/200x150" />
    </li>
    <li>
        <img src="https://dummyimage.com/300" />
    </li>
</ul>

However, I realized that what I am ultimately attempting is complicated and that I was better off just using a library: https://github.com/naturalatlas/image-layout

Antyos
  • 455
  • 5
  • 11