Responsive images
developer.mozilla.org
developer.mozilla.org
It makes it impossible to choose the "correct" image without using JS if the amount of space the image will take up of the viewport is determined in some relative manner (i.e. basically always).
For example, If I have a container with width: 10em, and then in there an image with width: 50%. I want to just e.g. specify 3 alternative images with widths 200px, 400px, 800px. The browser knows the exact pixel size the image will actually be, so why can't it just choose the best one? Why do I have to specify which one to use based on the viewport width instead of the actual image width? It's impossible to calculate that unless your image is a known fixed ratio of the viewport or by asking the layout engine for the computed width (with JS).
There's an answer about this being impossible by one of the spec authors here: https://stackoverflow.com/questions/38684928/correct-sizes-f... But it doesn't explain at all why it was done this way, I don't even know when I would ever prefer to specify the chosen image in the way the spec currently requires.
For your example I believe it would be done like so:
<img src="cat-200.jpg" alt="cat" srcset="cat-200.jpg 200w, cat-400.jpg 400w, cat-800.jpg 800w" sizes="5em">
This page explains responsive images further: https://cloudfour.com/thinks/responsive-images-101-part-5-si...
Basically, you want container queries, something long desired. It’s actively in the works but it’s first going to be for elements. Once that is working, it can inform how to implement it for responsive images.
So on a image heavy site, I might deliver 3x sized images (which may several megabytes) to an top generation iPhone in the middle of nowhere (like rural Germany) on a Edge connection...
I wish there was a CSS media query that would also consider the current network connection.
[1] https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pref...
But wasn't progressive JPEG and AVIF pretty much designed to alleviate this problem though? Webp does not seem to support progressive loading however.
- 1x vs. 2x dpi for high-density monitors
- png/jpg + webp + avif
I don't create additional screen-optimized image versions, as the work would require 6 additional files per screen resolution.
It's already quite some work, but I think it is worth it. Especially AVIF is often significantly smaller than other formats. I recently wrote a short guide on this topic [1].
Additionally to your technique I defined a really small image as a background image in order to get a “progressive loading for avif” kind of effect on slower connections.
It is a progressive image format which has an amazing feature: you can terminate the bitstream at any point during the download and have a good looking image. So servers could keep the high resolution of an image but send over just the first (for example) 20% when client is on mobile, and send 50% of the file for laptop, and all 100% when users are on a 4K television.
https://cloudinary.com/blog/time_for_next_gen_codecs_to_deth...
https://cloudinary.com/blog/improve_the_web_experience_with_...
Progressive JPEG is already supported but JPEG XL seems much better.
First time I hear about JPEG XL. I have experimented with progressive JPEG a couple of years ago but switched to webp since the various public Google page scores give a better score for images in webp.
chrome://flags
Search for `jxl` (pronounced "jixel") and enable it. Then visit https://jpegxl.info/ as well as the gallery: https://jpegxl.info/jxl-art.html
- Look at its device width.
- Work out which media condition in the sizes list is the first one to be true.
- Look at the slot size given to that media query.
- Load the image referenced in the srcset list that has the same size as the slot or, if there isn't one, the first image that is bigger than the chosen slot size.
> ---
Where many people's understanding falls short is the essential importance of the sizes value. In short, get that wrong and the browser is more likely to pick a suboptimal image from the srcset. Put another way, focusing on the scrset - which many seem to do - doesn't help if the sizes value misleads the browser about the nature of the image needed.
I found this artcle some time ago and it changed my understanding for the better. It's not new, but it doesn't need to be.
https://ericportis.com/posts/2014/srcset-sizes/
p.s. I do a lot of WordPress work. It's fine with srcset but usually pretty bad with sizes equal. Even Gutenberg isn't much better. That's right, 35% of the internet is doing this poorly.
Again, that article I shared does a great job of explaining. I'll re-read to find out about 1x, 2x, etc.
One example would be a logo that is less than 320px wide (so it fits even on mobile). In that case you can add x descriptors to give a higher quality logo on retina screens. e.g.
<img src="logo.jpg" alt="Logo" srcset="logo.jpg, logo-2X.jpg 2x">
Alternatively use an svg :)
But if the image depends on the viewport width then 'srcset' (without x descriptors but with w descriptors) and in combination with 'sizes' is the way to go.
So make sure you use a CDN or plugin that optimizes all image files.
In fact, for example, if you have 3 images sizes registered, say 100px wide, 500px wide, and 1000px wide, and you upload an image 800px wide, native WP will not produce the 1000px wide image. It can't. It will only resize / crop down. It won't take an image an stretch it.
There's browser plugins that will loop through your entire media library and ensure they're optimized. TinyPNG and Smush are well-known ones.
So I have to optimise them all, now it is done automatically.
Already discovered recently about loading="lazy" when loading a lot of image in a page...
In my opinion your best bet is to forget about all this px-fuckery and drop the `<img>` all together. Use a `<div>` with a `background-image`, and use media queries to control how the `background-image` is cropped, zoomed, or whatevered.
In general, `<img>` is a huge pain in the ass. It seems to defy all known layout rules and models, and I pretty much never want it to take up the x*y pixels that the image source is. I want it to take 100% of the width, or contain and crop it in 100% of the height, but all of this is notoriously annoying with an `<img>` tag. Seriously, use a `div` with a `background-image`. The semantics of having an image in an `<img>` tag don't matter, no one cares about it and your users won't notice it.
https://css-tricks.com/almanac/properties/o/object-fit/
I'd also suggest reading this. Having to write ultra-complicated media queries (width + resolution, etc.) feels friction-y. Instead, use sizes and scrset and the browser will take care of the rest.
"The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length. For a nominal arm’s length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm’s length, 1px thus corresponds to about 0.26 mm (1/96 inch)." [1]
I'll just use cm, thanks
I get movies/games, but day to day browsing seems like just extra slowness?
And as other have said, use object-fit.
The point is it should be the same on 2K monitor with 1x scaling AND 4k monitor with 2x scaling.
Using the HTML markup allows the browser to load the images sooner instead of having to wait for the CSS to be downloaded, parsed, and evaluated.
And there is nothing preventing you from selecting a larger image on a 2K/4K display if you have it, or using CSS to provide additional cropping, zooming, etc.