skip to Main Content

I have a figure with a caption, like this:

<figure>
<img src="image.jpg"/>
<figcaption>Caption</figcaption>
</figure>

I also have img{max-width:100%} in my CSS.

I want to set both the width and height of the image, and preserve its aspect ratio when the width is reduced by the max-width below its set value. So, I tried this:

<figure>
<img src="image.jpg" width="100" height="200" style="object-fit:contain"/>
<figcaption>Caption</figcaption>
</figure>

This is roughly what I want, but, when the image is ‘letterboxed’, the caption ends up a long way from the bottom of the image.

Is there a way to get the result I want, while keeping the caption immediately below the bottom of the image?

2

Answers


  1. If you’re using object-fit: contain, the image’s original aspect ratio is already being retained because the entire image has to fit within its parent. So if the image is originally 100px wide and 150px tall and you have your image set to width: 100px and height: 200px, the image’s height will still be 150px, but an extra 25px of space will be added to the top and bottom of the figure element.

    To fix this, all you have to do is set height to "auto."

    img {
      // moving your style declarations here for readability
      width: 100px;
      max-width: 100%;
      height: auto;
      object-fit: contain;
    }
    

    Now, if you’re actually trying to define the width and height and force the image to conform to that, you should be using something other than object-fit: contain. You can read about your other options here, but maybe you’re trying to set the width/height of the figure element and have the image fill that space. In that case, you could do something like this:

    figure {
        display: block;
        width: 100px;
        max-width: 100%;
        height: 200px;
    }
    img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        background: blue;
    }
    
    Login or Signup to reply.
  2. If you want the aspect ratio to stay the same no matter what image is loaded (i.e.: if the image comes back from an API and are unpredictable), you can use the aspect-ratio css attribute achieve your desired result of maintaining the aspect ratio of the image while also keeping the caption immediately below the bottom of the image.

    HTML:

    <figure class="image-figure">
      <div class="image-container">
        <img src="image.jpg" width="100" height="200" />
      </div>
      <figcaption>Caption</figcaption>
    </figure>
    

    CSS:

    .image-figure {
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
    }
    
    .image-container {
      aspect-ratio: 1 / 2; /* Width / Height ratio */
      max-width: 100%;
    }
    
    img {
      max-width: 100%;
      max-height: 100%;
      width: auto;
      height: auto;
      object-fit: contain;
    }
    

    Explanation:

    1. The image-figure class is applied to the figure element to set up a flex container with a column layout for proper alignment.
    2. The image-container div contains the image and is assigned an aspect ratio of 1:2 (width:height) to maintain the aspect ratio of the image.
    3. The max-width: 100%; on the image-container ensures that the image doesn’t exceed its container’s width.
    4. The img styles ensure that the image scales down to fit within its container while preserving its aspect ratio and using object-fit: contain.
    5. The caption remains immediately below the image due to the flex column layout.

    This approach combines the aspect-ratio CSS attribute with flex layout to achieve your desired result. The caption will stay positioned below the bottom of the image even when it’s letterboxed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search