4

From other questions here on SO, I've come to the point where I can maintain the aspect ratio an image, center it in a container both horizontally and vertically, and make it shrink to fit the container. Almost there!!!

What's wrong? I'd like to expand small images, and optionally be able to add a class to the <img> tag i.e. <img class="nogrow" ... /> to turn off the feature of expanding small images.

JSBin

.parent {
  width: 240px;
  height: 160px;
  border: 1px solid black;
  position: relative;
}

.img-container {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;

  text-align:center;
  font: 0/0 a;
}

.img-container .centerer {
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.img-container img {
  vertical-align: middle;
  display: inline-block;
  max-height: 100%;
  max-width: 100%;
}
<table>
<thead>
  <th>Actual</th>
  <th>Expected</th>
</thead>
<tbody>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/1000x500" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/1000x500" alt="" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/500x600" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/500x600" alt="" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/50x60" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/50x60" alt="" height="100%" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/100x50" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img src="http://placehold.it/100x50" alt="" width="100%" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <th colspan="2">With ".nogrow"</th>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/1000x500" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/1000x500" alt="" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/500x600" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/500x600" alt="" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/50x60" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/50x60" alt="" />
        </div>
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/100x50" alt="" />
        </div>
      </div>
    </td>
    <td>
      <div class="parent">
        <div class="img-container">
          <div class="centerer"></div>
          <img class="nogrow" src="http://placehold.it/100x50" alt="" />
        </div>
      </div>
    </td>
  </tr>
</tbody>
</table>
Community
  • 1
  • 1
Assimilater
  • 944
  • 14
  • 33
  • 1
    With little JS this can be tackled, but I have been wishing some pure-css resolution for some amount of time. – Season Aug 11 '16 at 08:51
  • @Season It seems to come up from time to time, and somehow I made do something less than ideal in the past :/ but ya I'd really like there to be a pure css solution – Assimilater Aug 11 '16 at 08:57

1 Answers1

4

Try object-fit: contain (and none or scale-down for .nogrow). You shouldn't need any divs at all, just set the dimensions of the image to 100% by 100%.

<!DOCTYPE html>
<style>
 td { width:240px; height:160px; border:1px solid }
 img { width:100%; height:100%; object-fit:contain; display:block }
 .nogrow { object-fit:scale-down }
</style>
<table>
 <tr><td><img src="http://placehold.it/1000x500" alt="">
 <tr><td><img src="http://placehold.it/500x600" alt="">
 <tr><td><img src="http://placehold.it/50x60" alt="">
 <tr><td><img src="http://placehold.it/100x50" alt="">
 <tr><th>With ".nogrow"
 <tr><td><img class="nogrow" src="http://placehold.it/50x60" alt="">
 <tr><td><img class="nogrow" src="http://placehold.it/100x50" alt="">
</table>
zcorpan
  • 1,243
  • 6
  • 11
  • So I was only using the table to display expectation vs reality side by side, there's no table in my actual use case. However, this seems to be exactly what I'm looking for. And it's so much simpler it kind of makes me mad, happy, and sad all at the same time lol – Assimilater Aug 11 '16 at 16:00
  • To work with generic, responsive types the parent (in this case ``) should have `position: relative`. Also, I don't think `display: block` is necessary for `` – Assimilater Aug 11 '16 at 16:01
  • Might be of worthwhile to update your answer with the full set of tests: http://jsbin.com/gaxegemudi/1/edit?html,css,output – Assimilater Aug 11 '16 at 16:04
  • 1
    You're right that `display: block` is not necessary, but without it there is some space under the images in no-quirks mode (since images are inline by default and sit on the baseline in a line box, and a line box has some space below the baseline for characters like "j"). – zcorpan Aug 12 '16 at 13:15