Is there an equivalent to background-size: cover and contain for image elements?

I have a site with many pages and different background pictures, and I display them from CSS like:

body.page-8 {
    background: url("../img/pic.jpg") no-repeat scroll center top #000;
    background-size: cover;
}

However, I want to show different (fullscreen) pictures on one page using <img> elements, and I want them to have the same properties as the above background-image: cover; property (the images cant be displayed from CSS, they must be displayed from the HTML document).

Normally I use:

div.mydiv img {
    width: 100%;
}

Or:

div.mydiv img {
    width: auto;
}

to make the picture full and responsive. However the picture shrinks too much (width: 100%) when the screen gets too narrow, and shows the body's background-color in the bottom screen. The other method, width: auto;, only makes the image full size and does not respond to the screen size.

Is there a way to display the image the same way that background-size: cover does?


Solution 1:

Solution #1 - The object-fit property (Lacks IE support)

Just set object-fit: cover; on the img .

body {
  margin: 0;
}
img {
  display: block;
  width: 100vw;
  height: 100vh;
  object-fit: cover; /* or object-fit: contain; */
}
<img src="http://lorempixel.com/1500/1000" />

See MDN - regarding object-fit: cover:

The replaced content is sized to maintain its aspect ratio while filling the element’s entire content box. If the object's aspect ratio does not match the aspect ratio of its box, then the object will be clipped to fit.

And for object-fit: contain:

The replaced content is scaled to maintain its aspect ratio while fitting within the element’s content box. The entire object is made to fill the box, while preserving its aspect ratio, so the object will be "letterboxed" if its aspect ratio does not match the aspect ratio of the box.

Also, see this Codepen demo which compares object-fit: cover applied to an image with background-size: cover applied to a background image


Solution #2 - Replace the img with a background image with css

body {
  margin: 0;
}
img {
  position: fixed;
  width: 0;
  height: 0;
  padding: 50vh 50vw;
  background: url(http://lorempixel.com/1500/1000/city/Dummy-Text) no-repeat;
  background-size: cover;
}
<img src="http://placehold.it/1500x1000" />

Solution 2:

Assuming you can arrange to have a container element you wish to fill, this appears to work, but feels a bit hackish. In essence, I just use min/max-width/height on a larger area and then scale that area back into the original dimensions.

.container {
  width: 800px;
  height: 300px;
  border: 1px solid black;
  overflow:hidden;
  position:relative;
}
.container.contain img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  max-width: 10%;
  max-height: 10%;
  -webkit-transform:scale(10);
  transform: scale(10);
}
.container.cover img {
  position: absolute;
  left:-10000%; right: -10000%; 
  top: -10000%; bottom: -10000%;
  margin: auto auto;
  min-width: 1000%;
  min-height: 1000%;
  -webkit-transform:scale(0.1);
  transform: scale(0.1);
}
<h1>contain</h1>
  <div class="container contain">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>
  <h1>cover</h1>
  <div class="container cover">
    <img 
       src="https://www.google.de/logos/doodles/2014/european-parliament-election-2014-day-4-5483168891142144-hp.jpg" 
       />
    <!-- 366x200 -->
  </div>

Solution 3:

There is actually quite a simple css solution which even works on IE8:

.container {
  position: relative;
  overflow: hidden;
  /* Width and height can be anything. */
  width: 50vw;
  height: 50vh;
}

img {
  position: absolute;
  /* Position the image in the middle of its container. */
  top: -9999px;
  right: -9999px;
  bottom: -9999px;
  left: -9999px;
  margin: auto;
  /* The following values determine the exact image behaviour. */
  /* You can simulate background-size: cover/contain/etc.
     by changing between min/max/standard width/height values.
     These values simulate background-size: cover
  */
  min-width: 100%;
  min-height: 100%;
}
<div class="container">
    <img src="http://placehold.it/200x200" alt="" />
</div>