(Similar questions are already asked at stackoverflow, but this question has more constraints, such as both a specific max-width, max-height, a required specific height and width, and no layout shift.)
Problem:
I want to have a responsive image with the following constraints:
- max-width: 100%, so that it doesn't overflow to the right, and that it is responsive when reducing the screen width.
- max-height: 200px, so that large images are reduced in rendered dimensions.
- height and width html attributes set, so that the browser can precalculate the required image dimensions, so that the layout doesn't shift/move elements beside/below the image, while the image is loading. (To reduce the cumulative layout shift.)
- image aspect ratio should stay 1:1
- no extra margins should be created around the image
- the image should be rendered with a plain html img tag, not with css background-images
- the image should not be rendered in a larger dimension than its original dimension
How can I achieve this with CSS?
(If CSS cannot achieve this, then maybe in JavaScript?)
What I tried
I tried several CSS features, such as object-fit and max-width: 100% etc, but I always get at least one of the contraints failing while trying to fix another constraint. For example, object-fit creates margins/paddings for the image when it's reduced in size when the screen size reduces, as if the image border isn't reduced. This is demonstrated in the following code:
https://codepen.io/Devabc/pen/mdVvyKq
/* Should appear to the right of the Wombat */
.beside {
float: left;
background-color: lightgreen;
border: 1px solid;
height: 200px;
width: 100px;
}
/* Should appear below the Wombat */
.below {
background-color: red;
border: 1px solid;
width: 100px;
height: 300px;
clear: both;
}
img {
display: block;
float: left;
max-width: 100%;
max-height: 200px;
border: 1px solid;
/* Without this, aspect ratio is not normal.
But with this, it creates an unwanted margin. */
object-fit: scale-down;
object-position: left;
}
<img
height="533"
width="799"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Vombatus_ursinus_-Maria_Island_National_Park.jpg/800px-Vombatus_ursinus_-Maria_Island_National_Park.jpg"
/>
<div class="beside">This text should be directly to the right of the Wombat, without any margin between the Wombat and this text.</div>
<div class="below">This text should be directly below the Wombat, without any margin between this and the Wombat.
The dimensions of the original Wombat img are:
width: 799px, height: 533px</div>
(The green text should be to the right of the Wombat, without margin. But object-fit causes a padding/margin to appear with the length of the original image.)
It's feels almost as if this isn't possible with CSS, even though these requirements shouldn't be too much to ask nowadays, with responsive design being important.
How can I fix this with HTML/CSS?