top | item 39959813

How to think about HTML responsive images

201 points| danburzo | 1 year ago |danburzo.ro

45 comments

order

fifticon|1 year ago

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.

jraph|1 year ago

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.

safety1st|1 year ago

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.

danburzo|1 year ago

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.

[1] https://ashleemboyer.com/blog/why-you-should-use-px-units-fo...

drcongo|1 year ago

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)

aembleton|1 year ago

> 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.

rchaud|1 year ago

I always open an image in a new tab. I can pan and zoom as much as I want there.

frankzander|1 year ago

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.

omnimus|1 year ago

I dont think topic thst can be explained in one blogpost is the most complicated thing in webdev.

People often just dont understand srcset/sizes and try to do too much and make some kind of media queries logic instead of leaving all to browser.

lobsterthief|1 year ago

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.

azangru|1 year ago

> I don't get it why ppl complain about how difficult CSS is ...

It's a huge language. There are so... many... properties.

nicbou|1 year ago

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.

danburzo|1 year ago

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.

Lorin|1 year ago

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.

Would love to know the rationale.

globular-toast|1 year ago

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.

falcor84|1 year ago

I'm not sure, but my understanding was that this is to reduce browser fingerprinting.

javman|1 year ago

The server doesn't know what size the image will be displayed, but the browser does.

omnimus|1 year ago

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?

liampulles|1 year ago

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.

est|1 year ago

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.

lobsterthief|1 year ago

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.

CGamesPlay|1 year ago

What problem does this solve?

orliesaurus|1 year ago

Looks like the verbose <picture> approach would be the most advantageous for backwards and forwards compatibility

stefanfisk|1 year ago

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.

perardi|1 year ago

I just have to compliment the lovely external link motif here.

danburzo|1 year ago

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.

https://practicaltypography.com/

victorbjorklund|1 year ago

Well-written. Will def come back to this.

danburzo|1 year ago

Thank you for the kind words!

troupo|1 year ago

So, the question remains: how do I supply various dynamic densities in different formats?

danburzo|1 year ago

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:

    <picture>
      <source srcset='…' sizes='…' type='image/avif'>
      <source srcset='…' sizes='…' type='image/webp'>
      <img srcset='…' sizes='…'>
    </picture>

If this is what you mean, maybe it would be better to include in the article?

knallfrosch|1 year ago

Now you just need to know at which size your image will be displayed at in a flex container and you're done :))

ryebread777|1 year ago

Very helpful! I will come back to read more deeply. But in general, what approach would you recommend?

danburzo|1 year ago

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.