Search code examples
javascripthtmlcss

How to make the image responsive gradually/smoothly (Reduce width first, then height)


I have an image that I want to be seen well in responsive mode, unfortunately, due to its large width, its height is too small on the phone!

There is a way that we can set an average height so that the height is not reduced too much, BUT its not an accurate method:

object-fit: cover;
min-height: 250px;

So the idea that came to my mind is to set a width range. and Reduce the width first, then the height.

Is this possible?:

whenever the browser was zooming out and wanted to reduce the height of the image, it should first reduce the width of the image (cover - zoom). gradually/smoothly up to the specified range (10% from the right and left) Then reduce the height while maintaining the reduced dimensions.

my code:

.ihero img {
width: 100%;
}
<a class="ihero" href="https://example.com/">
<img src="https://i.sstatic.net/fzY3Uxj6.jpg">
</a>


Solution

  • Yes, you can achieve what you want to achieve, but you do need media queries to implement different styling at different viewport widths.

    Your source image is 2560x600 pixels in size, but I’m assuming that you want to treat it as a @2x image, so in terms of CSS pixels we consider it to be 1280x300. With 10% cropped off each side, the image would be 2048x600, or 1024x300 in CSS pixels.

    1. The overall strategy is to wrap the image in a container, constrain the container in various ways, set the image to fill the container and set object-fit: cover so that it will crop automatically.
    2. At widths below 1024 pixels we constrain the container’s aspect-ratio to 1024/300. 20% of the image width is cropped, 10% from each side.
    3. At widths between 1024 and 1280 pixels we constrain the container’s height to 300 and unconstrain the aspect-ratio. The crop varies smoothly from 20% at 1024 pixels to 0% at 1280 pixels.
    4. At widths above 1280 pixels, both height and aspect-ratio can both be auto (or initial). The image is not cropped.

    A snippet to demonstrate. After running it, make sure to use the full page link to test the responsive behaviour.

    body {
      margin: 0;
    }
    
    a.ihero {
      aspect-ratio: 1024/300;
      border: 2px solid red;
      display: block;
    }
    
    @media (min-width: 1024px) {
      a.ihero {
        aspect-ratio: initial;
        height: 300px;
      }
    }
    
    @media (min-width: 1280px) {
      a.ihero {
        height: auto;
      }
    }
    
    a.ihero img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
    }
    <a class="ihero" href="https://example.com/">
      <img src="https://i.sstatic.net/fzY3Uxj6.jpg">
    </a>

    After running this snippet, make sure to use the full page link to test the responsive behaviour.