One frequent unpleasant side-effect of responsive design, is sites that resize themselves when you try to zoom the page.
For images, this sometimes turns bizarre:
If you try to zoom the current webpage to more clearly see details of an image, the web page will try to "help" you by resizing the image to continue to fit in your viewport.
The net result is, that the image often gets even smaller when you try to zoom (because neighbour elements like text still grows).
Reddit is one of the sites guilty of this.
Worse, they even do it if you "open image in new tab".
I have surrendered on this, and instead just DOWNLOAD the image to disk, to then reopen it in a separate tab, to finally zoom it.. Sigh.
When I find myself in such a situation, I pinch zoom with the touchpad or the touchscreen if reachable in the setup I'm using. On Firefox on Linux it doesn't reflow.
Of course, I sometimes end up with a zoom mess where the page is zoomed, and then pinch zoomed.
It's always morbidly interesting to speculate on how a user-hostile behavior like Reddit's image handling exists. Like, the default things that browsers do if you put in no effort beyond an img tag, work better than this. To make an experience as shitty at Reddit's takes a lot of time and effort. At Silicon Valley dev rates they must spend many millions of dollars just making stuff worse.
Remember when Google used to be cool and was basically just making simple tools that were on the web? I have not seen that philosophy of engineering come from Big Tech in many many years.
Oh yeah, definitely something I’ve witnessed and been frustrated by before. Some of it stems from improper use of CSS units [1], and the only real recommendation I have is for people to _test_ for basic things like zooming in and out of the page, while keeping close in mind _the reasons_ people might want to zoom in and out of the page.
Pro tip: If you pinch to zoom it should zoom the entire page including the image, instead of increasing the size of elements inside the html as a Cmd+ does. (MacOS, any browser)
> Worse, they even do it if you "open image in new tab".
How does it know where to get the CSS or picture element from to manage that? Maybe it keeps it from the other page. Does this happen in all browsers? I don't think I've seen this in Firefox.
When you navigate to https://i.redd.it/dl34o62azctc1.jpeg, Chrome sends (I'm doing this on Chrome because I think I've made some hacks in Firefox to fix this)
GET https://i.redd.it/dl34o62azctc1.jpeg
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Reddit redirects images you attempt to open in a new tab back to an image viewer within Reddit, so you aren't just loading the image in a tab like you would be on most sites.
To be honest ... this is IMHO by far one of the most complicated thing in the whole webdev area.
I don't get it why ppl complain about how difficult CSS is ... but to foresee how an image behaves and find a good balance between size and file size is a hart thing to juggle with.
This article clarifies a lot of things for me so thx for that.
Also, teaching non-engineers about the different file types to use (like not using PNGs for raster content) is another realm of complexity.
Optimizing images programmatically is easy. Converting them between PNG and JPG programmatically, along with determining when such a conversion should happen, is very difficult.
Well done! Having read the source documents a few times, I wish that your article existed before. It took me a while to wrap my head around the concepts and to get them to work properly.
Thank you for the kind words! I have fun reading specs, but the HTML Standard is denser and organized more… cross-referentially than the average CSS spec, so there was a bit of putting-things-together.
I have no idea why browsers moved away from providing the DPR (device pixel ratio) header on media requests so one could continue using the sensible and simple <img> whilst the server could return the correct images on its own.
Doesn't work for static sites. At one point it seemed like home computers would be going away and everyone would just use small, thin clients with most of the "work" done on servers. I'm glad this hasn't happened. I prefer the idea of a static site where the user's browser makes all the decisions.
I haven’t followed Client Hints closely, but a change[1] in RFC 9842 internal drafts “removed specific features to be defined in other specifications”, and the `DPR` header ended up as `Sec-CH-DPR` in the nascent Responsive Images Client Hints spec[2].
Isnt it same reason why using srcset device ratio is not recommended and you should use widths.
Sending DPR in header is kinda useless and maybe hurts privacy/fingerprinting?
I like the approach of displaying a smaller compressed version and enclosing the img in an a tag to link to the larger image.
Let me load the page quickly if the doggo is just being used as an aside to the main content. Let me click on it to get the full raw image if I'm so enticed by that over the shoulder glance.
Is it possible to serve one image file of progressive encoding and display different size on different media conditions?
As a hack I would just put the blob offset in the URL as part of file name, and use js to load those images.
For example:
filename.1000-120w.3000-240w.5000-360w.jpg
means the 0-1000 bytes will get you 120w image, 0-3000 bytes will get you the 240w image, 0-5000 bytes will get you the 360w image, and load full will get you the original image. Make an http request with a Content-Range header and render the result with canvas or something.
The ideal of an image format the can progessively support different sizes was discussed back when solutions to the responsive image issue were first being sought out e.g. https://blog.yoav.ws/posts/responsive_image_container/
What you’re describing is sort of how sprites used to work. They aren’t used as much anymore.
Basically, a bunch of small images would be combined into a single image (like a grid), and then that single image would be loaded and would use background-size and background-position to display the image in a background-image. One request for a large number of small images. This isn’t used as much now that SVGs are so widely supported and can be themselves inlined.
But at that point, since you're not optimizing for filesize (everyone fetches every size), you might as well just provide the highest quality version only
Having the server decide the image format based on the accept header is simpler. Services like https://imagekit.io/ (no affiliation) can do that for you.
Yes, a smart server (that does more than serve static image assets) can do the heavy lifting and alleviate some of the HTML markup complexity.
It has the `Accept` header as a guide to what image formats the client supports, and with Responsive Image Client Hints[1], it can opt into more info from the client (device pixel ratio, image layout width, viewport width).
Without relying on server features, `<picture>` with `<source type='…'>` is the way to serve images in newer formats without breaking in less capable browsers.
It’s interesting that `image-set()`, the CSS sort-of counterpart to `<picture>`, bakes in the media type along with the resolution in a single syntax [2]. Which you could potentially see happening in `srcset`, but it makes the descriptive/prescriptive boundary a bit blurry, so it would complicate things IMO.
Thank you! I must have picked up the idea from from Matthew Butterick’s “Practical Typography”, but with the symbol drawn rather than as the degrees character, to spare screen reader users from hearing that constantly.
I haven’t explicitly mentioned it in the article, but `srcset` + `sizes` is a way to provide dynamic densities for one image format, then multiply that with one `<source>` for each image format:
With the goal of showing nice, clear images to as many devices as possible, while optimizing the file size, I would:
1. decide if I want to use any of the newer image formats. If so, each needs its own `<source type=''>` in a `<picture>` element, front-loading the most efficient formats.
2. decide if I want to serve different densities for the image.
For specifying densities, width descriptors + `sizes` attribute will always compute to a more useful effective density than density descriptors, if you can get `sizes` in the ballpark of how the image is actually laid out.
For lazily-loaded images, `sizes=auto` will do that for you, when it becomes universally supported.