Object-fit: Cover and Srcset

4.2k views Asked by At

I am using object-fit: cover on a bunch of images. The frame for the image takes up 50vw and has a dynamic height. The cover attribute works great, but it means that I don't really know how wide my actual image will be at a given time.

Most likely it will be wider than the 50vw and will have its overflow hidden due to the object-fit cover.

The problem comes in when I try to use srcset. I am unable to give a reliable width for the sizes attribute.

I know that size only needs an approximation, but I am curious if anyone has dealt with this before.

5

There are 5 answers

1
Wayne R Hendricks On

You can add width, height, min- & max-width or height as attributes on the srcset like this.

 <picture>
   <source srcset="images/w350/1.png" media="(max-width: 576px)" width="358px"
                  height="250px">
   <source srcset="images/w500/1.png" media="(max-width: 991px)" width="502px"
                  height="350px">
   <img src="images/1.png" data-src="images/1.png">
 </picture>
2
roye7777777 On

This doesn't specifically answer this question, but in the end, if nothing helps... one can think out of the box and if semantics isn't an issue (often that is though), then one can still use background-image and let that render conditionally by media query's. If a media query isn't matched, it won't download the background-image within and background-size has better support than object-fit anyway.

2
Zlerp On

Not sure, but this is what I do for almost all my dynamic images:

I make a <div> and make it whatever size I want, and set the image inline as the bg of the div (cause most templating langs you cant set in CSS).

.ratio {
  width: 50vw;
}

.ratio-4-3 {
  padding-top: 75%;
}

.vh-100 {
  height: 100vh;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<div class="d-flex">
  <div class="flex-child">
    <div class="ratio ratio-4-3"style="background: url('https://i.cdn.turner.com/adultswim/big/img/2018/05/07/rick-and-morty.jpg')no-repeat center center; background-size: cover;"></div>
  </div>
  
    <div class="flex-child">
    <div class="ratio vh-100"style="background: url('https://cnet3.cbsistatic.com/img/NMPqQxi-Gbz3JS9Q1BpqpMfG-AQ=/1600x900/2017/03/24/80d3cf97-5aae-4750-b856-53c89005dbc1/rickandmorty3.jpg')no-repeat center center; background-size: cover;"></div>
  </div>
  
</div>

0
Nikhil Kumar On

You could give srcset based on media queries, first figure out the ratio of image. then you can determine how much the image will be visible in 50vw on each screen-size.

1
Miloš Miljković On

Your question arises the problem of art direction combined with the problem of content delivery. Art direction is essentialy the decisions you make for the format of your content (i.e. when refferring to images: wide image, close-up, portrait, square etc.), the solution is to create differrent, cropped versions of your photo and use them accordingly with the srcset attribute, for instance you may have a wide image that on small screen should be "cropped", thus you would use something like this:

<picture>
  <source media="(max-width: 799px)" srcset="wide-image-480w-close-up.jpg">
  <source media="(min-width: 800px)" srcset="wide-image-800w.jpg">
  <img src="wide-image-800w.jpg" alt="A wide image">
</picture>

The other problem, that of content delivery is what content is being delivered and when, this is also solvable with the srcset attribute mentioned above.

Your case seems to be dependent on both height and width of the container of the image, so you should be looking for breakpoints in your aspect ratios so the example should feature aspect-ratio rule like this

<picture>
  <source media="(min-aspect-ratio: 8/5)" srcset="wide-image-480w-close-up.jpg">
  <source media="(max-aspect-ratio: 3/2)" srcset="wide-image-800w.jpg">
  <img src="wide-image-800w.jpg" alt="A wide image">
</picture>

However in some instances you may need more granular control as aspect ratio and width of the viewport may not correlate with the image used so you should watch for the width as well, this is accomplished by using the and operator in your @media rule, so the above can combine into this:

<picture>
   <source media="(max-width: 799px) and (min-aspect-ratio: 8/5)" srcset="wide-image-480w-close-up.jpg">
   <source media="(min-width: 800px) and (max-aspect-ratio: 3/2)" srcset="wide-image-800w.jpg">
   <img src="wide-image-800w.jpg" alt="A wide image">
</picture>

On final note I would like to point out that there are great services that provide powerful API's for image processing that make these kind of problems a breeze, also there is great content online regarding art direction and source content delivery, especially on the MDN's website, over here

UPDATE: We now have another css declaration that allows loose control over aspect ratios, it probably still can't provide a very concrete way of controlling the art direction completly but there are ways in which it would prove useful. The word is about apect-ratio css declaration and is very nicely explained in the following article: “Weak declaration”