25

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.

Suresh Karia
  • 17,550
  • 18
  • 67
  • 85
Andrew Whited
  • 281
  • 3
  • 6
  • The big question is do you know the aspect ratio of your images? – alexander farkas Jul 01 '15 at 18:48
  • 1
    The 'aspect-ratio' media query may be useful here. – Kevin Wheeler Mar 03 '16 at 06:45
  • I have the same problem; my image thumbnails are for images of varying aspect ratios. I am using object-fit: cover to achieve the square thumbnails. I am combining this with a feature where the image can be expanded to it's full size with a seamless animation, so that is the reason for using the original image and object-fitting it to a square. I feel like it should be the browsers responsibility to determine that it needs to fetch a larger size when displayed with object-fit, but for now I am just going to increase the sizes attribute so that hopefully most of the images end up looking okay. – Ben Cole Aug 11 '16 at 00:24
  • 3
    Please post a real image in a real `` tag inside a real `` tag that has real `srcset` attribute and include the`` as well – zer00ne Mar 06 '18 at 22:10
  • if you can use srcset, then just stop using `object-fit: cover;`. then you can give your images a height using media queries and use the srcset like you normally would – LuisBento Jan 27 '19 at 14:46
  • Could we get some more insight to this problem, as it seems to be an art-direction problem, it could really help to have some usecase to work with. – Miloš Miljković Aug 13 '20 at 07:04

5 Answers5

2

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”

  • Indeed, the main problem is when you display a landscape in a portait box (when you display an img 100vw and 100vh, it is landscape on desktop, and portait on mobile), so having this approach seems better. But it seems there is no way for the browser to know what width it has to display before downloading the image, since it depends on the img ratio itself... So yeah, looks like giving the right orientation is a good start... thanks – Random Mar 12 '21 at 23:08
0

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.

0

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>
  • What is the benefit doing this ? you don't want your box to change size. Let's say you have a box 50vh height, and 50vw width. You want to image to cover all that box, so use `object-fit: cover`. You've already set the width/height of your box. All you want is knowing what img quality you need to download for that screen size... without changing the size of the box. – Random Mar 12 '21 at 23:04
-1

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.

roye7777777
  • 394
  • 1
  • 2
  • 13
  • it doesn't change anything to the problem. if you set a media-query to `max-width: 480px`, knowing your box containing the img is `50vw` width, means you would expect downloading a `240px` width img inside your media-query, result would be blurred. Because you set the height to a constant too, if you display a landscape img inside a portait box, with `object-fit: cover` browser will display a 400px wide img, in a 240px wide box, hidding the overflow. So you would need a >400px wide img... – Random Mar 12 '21 at 23:01
  • I now sort of realise that I misunderstood the issue in here and I answered something entirely different. My bad. As put by the primary reply, it is indeed not possible to determine the width of an img in this context. Perhaps container queries could be useful in this case, once they become available. – roye7777777 Mar 18 '21 at 08:31
-2

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>
cmeeren
  • 3,890
  • 2
  • 20
  • 50
Zlerp
  • 467
  • 7
  • 16
  • Since he is using srcset, he is most likely providing differently sized images for different resolutions. Supplying the image as a background will not allow that. – Johan Dahl Apr 09 '20 at 06:27
  • @JohanDahl actually, you can set the background-image in your CSS file with media query. But indeed the problem remains the same... – Random Mar 12 '21 at 23:05