I had to solve the same task. I had to place several images with different aspect ratios to fullfill the thole width of the page (or container).
And I want them all to have the same height:

TL;TR
I found 2 pure CSS solutions for this task:
- Based on padding and margin properties behaviour for making a constant aspect ratio of elements
Source: https://wellcaffeinated.net/articles/2012/12/10/very-simple-css-only-proportional-resizing-of-elements
Define the width of an element as a percentage (eg: 100%) of the
parent’s width, then define the element’s padding-top (or -bottom) as
a percentage so that the height is the aspect ratio you need.
- Using flexbox for responsive equal height images preserving aspect ratio of images
Source: https://codepen.io/blimpage/pen/obWdgp
Set the flex property of each image's wrapper div to the image's
aspect ratio (its width divided by its height)
Both solutins assume you need to know the sizes of images to build proper CSS.
You can use server side scripts, e.g. PHP for this.
There are functions or libraries for this.
E.g., there is a getimagesize() function for PHP. (See https://www.php.net/manual/ru/function.getimagesize.php)
If need to place only several images, you can look up there sizes and hardcode it to the PHP script, that outputs the resulting HTML.
I will use this method for simplicity.
Another approach is to use calc() function in CSS.
Details
Solution 1. A pure CSS with padding attribute
Some explanations below.
Variables description:
- W - is a page/container width.
- H - is a block with images width. It's the same for any image.
- w0[i], h0[i] - is an original size of an i-th image.
- w[i], h[i] - is dispayed size of an i-th image.
- h[i]=H
Let's calculate ratios
W=SUM(w[i]), as images fullfill the width.
Let's divide it by H=h[i]:
W/H=SUM(w[i]/h[i])
Let's calculate an aspect ratio for an i-the image
r[i]=w[i]/h[i]=w0[i]/h0[i], as it has to be a constant for that image
So we get
W/H=SUM(r[i])
or H=W/SUM(r[i])
It's an aspect ratio for the whole container:
R=W/H=SUM(r[i])
So we can get H=W/R
An example of PHP code:
<?php
//Image sizes
$arImages = [
['NAME' => '11.png', 'W' => 1000, 'H' => 1000],
['NAME' => '12.png', 'W' => 1000, 'H' => 2000],
['NAME' => '21.png', 'W' => 2000, 'H' => 1000],
];
?>
<!DOCTYPE html>
<html>
<head>
<?php
$r = 0;
//Loop through all images
foreach ($arImages as $image) {
$w = $image['W'];
$h = $image['H'];
$r += $w / $h;
} ///Loop through all images
//The band height as a percentage of the window width
$hBand = (1 / $r) * 100;
?>
<style>
.page {
width: 100%;
}
.sh-band {
border: 1px solid blue;
padding: 0;
}
.sh-band-resizer {
width: 100%;
padding-top: <?= $hBand ?>%;
position: relative;
}
.sh-element {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.sh-element img {
width: auto;
height: 100%;
}
</style>
</head>
<body>
<div class="page">
<?
/**
* Proportional scaling with padding-top CSS
*/
?>
<div class="sh-band" style="">
<div class="sh-band-resizer">
<div class="sh-element"><?php
//Loop through all images
foreach ($arImages as $image) {
?><img src="/sh-gallery/images/<?= $image['NAME'] ?>"><?php
} // /Loop through all images
?></div>
</div>
</div>
</div>
</body>
</html>
HTML + CSS, produced by this code for sample images from the @s-j answer:
<html><head>
<style>
.page {
width: 100%;
}
.sh-band {
border: 1px solid blue;
padding: 0;
}
.sh-band-resizer {
width: 100%;
padding-top: 48.191461696405%;
position: relative;
}
.sh-element {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
.sh-element img {
width: auto;
height: 100%;
}
</style>
</head>
<body>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-9">
<div class="page">
<div class="sh-band" style="">
<div class="sh-band-resizer">
<div class="sh-element"><img src="https://i.stack.imgur.com/tDEmT.jpg"><img src="https://i.stack.imgur.com/WSp0o.jpg"></div>
</div>
</div>
</div>
</div>
</body></html>
Solution 2. A flexbox variant
You still need to know image sizes on the server side for building inline CSS.
The key idea is to set the flex property of each image's wrapper div to the image's aspect ratio, i.e its width divided by its height.
If you specify only 1 parameter to flex propery, is interpreted as flex: 1 0; (See https://developer.mozilla.org/en-US/docs/Web/CSS/flex )
So the flex-grow wil be set to image's aspect, flex-shrink to 1, flex-basis to 0;
(See The difference between flex-basis auto and 0 (zero) about "zero" flex-basis)
At first it shrinks images to minimal size (zero) and then stretches their width according to their aspect ratios to fulfil the full flex container width.
Explanations.
Variables description:
- W - is a page/container width.
- H - is a block with images width. It's the same for any image.
- w0[i], h0[i] - is an original size of an i-th image.
- w[i], h[i] - is displayed size of an i-th image.
- r[i]=w0[i]/h0[i]=w[i]/h[i] - an image's aspect ratio
- h[i]=H - images has to be with the same height
To determine actual width of the certain image we have to sum all the flex-grow factors.
R=SUM(r[i])
Then we can calculate an individual width and using constant aspect ratio we get
w[i]=r[i]*W/R=(w[i]/h[i])*W/R
Thus
h[i]=W/R
We can see that h[i] is constant for all the images, depends only on W/R.
Additionally we are using images aspect ratio saving by setting to auto the img height property.
(See https://css-tricks.com/flex-grow-is-weird/ )
A PHP sample:
<?php
//Image sizes
$arImages = [
['NAME' => '11.png', 'W' => 1000, 'H' => 1000],
['NAME' => '12.png', 'W' => 1000, 'H' => 2000],
['NAME' => '21.png', 'W' => 2000, 'H' => 1000],
];
?>
<!DOCTYPE html>
<html>
<head>
<style>
.page {
width: 100%;
}
.sh-band {
border: 1px solid blue;
display: flex;
}
.sh-element img {
width: 100%;
height: auto;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="page">
<?
/**
* Proportional scaling with flex
*/
?>
<div class="sh-band">
<?php
//Loop through all images
foreach ($arImages as $image) {
?>
<div class="sh-element" style="flex: <?= $image['W'] / $image['H'] ?>">
<img src="/sh-gallery/images/<?= $image['NAME'] ?>">
</div>
<?php
} // /Loop through all images
?>
</div>
</div>
</body>
</html>
A Bootstrap result code:
.page {
width: 100%;
}
.sh-band {
border: 1px solid blue;
display: flex;
}
.sh-element img {
width: 100%;
height: auto;
vertical-align: middle;
}
<html>
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body>
<div class="col-9">
<div class="page">
<div class="sh-band">
<div class="sh-element" style="flex: 1.319587628866">
<img src="https://i.stack.imgur.com/tDEmT.jpg">
</div>
<div class="sh-element" style="flex: 0.75546875">
<img src="https://i.stack.imgur.com/WSp0o.jpg">
</div>
</div>
</div>
</div>
</body>
</html>