Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Of the Sizes Attribute for Reponsive Images

I'm in the process of trying to wrap my head around using srcset and sizes on img tags.

Whilst I think I have grasped the basics – mainly thanks to this article – I'm struggling in practical application of the sizes attribute.

In all the examples I can find, things are massively simplified and the sizes attribute is declared as if at each breakpoint, the image width will be an exact proportion of the viewport width, allowing the use of vm units. For example:

sizes="(min-width: 36rem) 33.3vw,
       100vw"

Of course in real life, images are often within other containers which themselves might be within other containers and so on, each with their own margin, padding or positioning.

Is it fair to say that in all but the simplest cases (when images are of fluid width and are not simply an exact percentage of the viewport), calc must be used, potentially adding hideously complex calculations to the html markup as an images dimensions need to be calculated working from viewport width, down through any containers to the image? For example how would you calculate the correct size for an image located a container with 7px padding that is itself inside a container that is 45% of its container with 15px margin that is inside a sidebar that is 25% of the main page container which has 15px of padding and has a min-width of 1220px?

sizes="(min-width: 36rem) calc(((((1220px - (2 * 15px) * 25%) * 45%) - (2 * 15px) - (2 * 7px)),
       100vw"

Trying to calculate this in the sizes attribute seems ludicrous, especially given that all this might change at each breakpoint. having to keep this massively complex calculation in sync with changes to the CSS seems like madness. And then you have the patchy browser support for calc.

I feel like I'm missing something obvious, but what is it?

Note: I'm aware of Alexander Farkas's excellent Lazy Sizes which does the size calculations for you through the use of data attributes, but I'm interested in standard usage.

like image 934
Undistraction Avatar asked Aug 04 '15 09:08

Undistraction


1 Answers

First of all % units are not allowed in sizes. You must use vw units. (Which can include the scrollbar width). So your 25% becomes 24-25vw for example. Second there is no real difference between rem and em (in context of sizes attribute). In case you don't use em/rem based media queries / min-width/max-width in your CSS, never use those in your sizes attribute.

Basically sizes don't need to match your real image size 100% exactly. It is a tell for the browser to find the right image candidate approximately.

Your min-width: 1200px rule as also every max-width usage in your CSS, should be clearly part of a new media condition in your sizes attribute.

This leaves us with the following sizes part:

(min-width: 1200px) calc(11vw - 44px)

In case you add have a max-width defined or a media query that stops sidebar from growing, you can be less correct and simply transform 11vw - 44px into 10vw:

For example:

sizes="<...,>(min-width: 1800px) 180px, (min-width: 1200px) 10vw, <....>"

About calc support: picturefill 3.0 beta as also respimage, do include calc support for IE8+, so all browsers which do support sizes have good enough calc support and all respimage polyfilled browsers do support calc in sizes also.

About getting this straight. This is clearly painfull and in most cases your CMS/backend system should help here. In most projects you should agree upon a limited set of allowed image formats and write the sizes for those corresponding to your design. And your backend should manage to attach those sizes at the right place. In case this is not possible. Either use indeed lazySizes or use srcset with sizes at least for the most important images (i.e.: large image formats, because this is where you can save data most).


If you want you can pick a real website and we attach full correct sizes to it. But be aware. It must be only width constrained. The standard currently does not support height constrained images (This is a lazysizes feature only).

like image 191
alexander farkas Avatar answered Oct 05 '22 02:10

alexander farkas