Search code examples
htmlimagecssobject-fit

How to align text to image that is auto scaled with object-fit: contain


I have a viewport that takes up about 75% of the screen and I fit single images of varying aspect ratios into it using the object-fit: contain css. Above the image I have text labels for the file name & type. I want to keep these aligned to start at the left most edge of the image and end at the right most edge. I could do this easily before by aligning them to the <img> tag.

One side effect of using object-fit: contain is that the <img> element is bigger than the viewable picture, so when I try to align text to the <img> it can appear that the text is floating off of the image.

How can I align the text to the viewable image, when the img tag is expanded to fit the whole viewport but the actual picture is autoscaled inside the img tag using object-fit: contain?


Solution

  • The solution is very much dependent on markup, fixed widths and/or heights etc.

    Assuming you don't know their width/height in advance, you'll need a script, as in below sample.

    Updated: I added the opacity so the image and text display's at the same time.

    If you do know them, you still need to work out a bunch of CSS animation rules, covering their ratio and animation setting to make it look good, which can be done, though it will take some work. In the end of this answer is a sample how to set an element size based on the same way fit-content calculate size.

    document.querySelector('img').addEventListener('load', function(e) {
      document.querySelector('.image-text').style.cssText = 'width: ' + e.target.width +'px; opacity: 1;';
    })
    .image-wrap {
      position: relative;
      height: 200px;
      overflow: hidden;
      border: 1px dashed gray;
      margin-bottom: 10px;
    }
    
    .image-wrap img {         /*  fit-content replacement  */
      position: relative;
      max-height: 100%;
      max-width: 100%;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    
    div.image-text {
      opacity: 0;
      margin: 0 auto;
    }
    <div class="image-text">Some text we want to size and break at the same width as the image</div>
    <div class="image-wrap">
      <img src="http://placehold.it/500x400" alt="some image here" />
    </div>


    Here is another post about getting an images both natural and scaled size: