Re:Responsive images
by phiresky on Saturday June 12, 2021 @09:43AM
(#27484432)
I never understood why the `sizes` attribute has to be so complicated. Why do I have to decide on which image to choose based on the display size instead of it automatically choosing the best image based on the size the image is displayed as?
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.
Re:Responsive images
by superfad on Saturday June 12, 2021 @11:13AM
(#27485024)
The browser doesn’t know the size at which the image will be rendered on the page until it has downloaded and parsed all the relevant CSS and JavaScript files. Shortly after the browser downloads the HTML, it requests CSS and JavaScript. But before the CSS and JavaScript is done loading, the browser starts downloading images. The only thing that the browser does know is the size of the viewport. If we give sizes based on screen width then the browser will know which image to use. The width doesn’t have to be expressed as a viewport width unit though. It can be any length including absolute and relative length. You can even use CSS calc() to do things like auto-calculate margins dynamically.
For your example I believe it would be done like so:
Re:Responsive images
by extra88 on Saturday June 12, 2021 @10:50AM
(#27484876)
> 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.
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.
Re:Responsive images
by chrismorgan on Saturday June 12, 2021 @11:41AM
(#27485195)
Container queries are a red herring here; they don’t change anything at all. The question being asked here is “why doesn’t it just use the image’s size?” and the real answer to that is that you don’t want to wait for the CSS to all be loaded before fetching any images at all—that’d be a pessimisation, not an optimisation. Hence the sizes attribute cares about viewport sizes, and always will do. Container queries will almost certainly never get involved in this, because, along with the rest of CSS, they’re evaluated after image loading begins.
Re:Responsive images
by extra88 on Saturday June 12, 2021 @12:09PM
(#27485385)
You misunderstand me; one will not use container queries to load images responsively, responsive image standards will be changed in ways that are informed by how container queries are implemented.
Re:Responsive images
by chrismorgan on Sunday June 13, 2021 @07:51AM
(#27491768)
I did misunderstand you at least partially, but my point stands: container queries are part of CSS and layout, and I think it’s very unlikely that they will yield any new approach for responsive image source specifications, because making it work would require shifting waaaaay too much stuff into presentational HTML. What the sizes attribute covers is bad enough in this regard, but it’s at least straightforward to implement in an isolated fashion.
Re:Responsive images
by splitbrain on Saturday June 12, 2021 @08:52AM
(#27484113)
One thing that's annoying about responsive images is that the displays with highest density are built into the devices with the potentially shittiest bandwidth.
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.
Re:Responsive images
by darekkay on Saturday June 12, 2021 @12:41PM
(#27485597)
There is a prefers-reduced-data media query draft [1] which addresses the issue. It doesn't actually check the bandwidth, though (although I believe there are options to put a mobile phone into "reduced data" mode below a certain bandwidth).
Re:Responsive images
by Nextgrid on Saturday June 12, 2021 @09:18AM
(#27484290)
Progressive formats still require the device and network to allocate the bandwidth appropriately, so you'd want required traffic reaching the device first, and then images. The problem is that in most cases everything is just thrown more or less at once towards the device and then latency and packet loss goes through the roof and nothing loads.
Re:Responsive images
by darekkay on Saturday June 12, 2021 @03:19AM
(#27482356)
On my blog, I usually create and include 6 files for the same image:
- 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].
Re:Responsive images
by leipert on Saturday June 12, 2021 @03:39AM
(#27482457)
Ran into the same problem with my a recent website. I think I am still going to create at least one smaller version for mobile.
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.
Re:Responsive images
by yboris on Saturday June 12, 2021 @10:29AM
(#27484736)
JPEG XL may solve all these problems instantly:
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.
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.
Re:Responsive images
by rikroots on Saturday June 12, 2021 @06:50AM
(#27483507)
One thing I learned about responsive images - <img> elements with a srcset attribute - while developing my JS canvas library is that if you're relying on those <img> elements to as the source for your ctx.drawImage() calls then the whole thing blows up in unexpected ways when the user changes their browser's size.
> So, with these attributes in place, the browser will:
- 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.
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.
Re:Responsive images
by Santosh83 on Saturday June 12, 2021 @08:20AM
(#27483947)
Sizes is needed when you specify the intrinsic width of the image with the w descriptor I believe. Alternatively you can specify resolution factor (1x, 2x, etc) in which case the sizes attribute is not needed and the choice of which image to download is placed on the browser in a more autonomous manner than specifying sizes.
You might be correct. Regardless, the choice is always on the browser, as it should be. It's the only one who knows the screen res, how wide and tall, the markup, etc. With all that it picks.
Again, that article I shared does a great job of explaining. I'll re-read to find out about 1x, 2x, etc.
Re:Responsive images
by superfad on Saturday June 12, 2021 @01:15PM
(#27485884)
The only time the sizes attribute is not needed when using srcset is when the rendered size of the image is fixed.
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.
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.
Re:Responsive images
by frabjoused on Saturday June 12, 2021 @02:04AM
(#27481991)
Had to recently build a helper function in our templating engine to handle image tags - it's amazing how much markup you have to generate to get an image just right factoring pixel density, source sets, lazy loading and explicit width / height.
Re:Responsive images
by topicseed on Saturday June 12, 2021 @02:14AM
(#27482041)
Funny thing if you have WordPress. When you upload images, you may have compressed your image when saving the file from Photoshop, but WordPress automatically crops that image to various sizes based on your theme and plugins. Some of these cropped files can often be larger than the original full size file.
So make sure you use a CDN or plugin that optimizes all image files.
That's I believe that's incorrect. WP won't "crop up", unless you're using some special plugin.
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.
Re:Responsive images
by SquareWheel on Saturday June 12, 2021 @11:04AM
(#27484954)
I believe what they're saying is that the thumbnails Wordpress generates may be larger in file size because they're not rigorously optimized like your original image may be.
There's browser plugins that will loop through your entire media library and ensure they're optimized. TinyPNG and Smush are well-known ones.
Re:Responsive images
by topicseed on Saturday June 12, 2021 @03:08PM
(#27486750)
Yes, that's exactly what I meant. I optimise my uploaded images highly and when WP created the various sizes, the smaller pixel sizes often end up heavier in kb than the original.
So I have to optimise them all, now it is done automatically.
I'd like to see that. That would mean either WP is adding meta to the image file (which I'm pretty sure it doesn't do), or WP is making a lower quality jpg in higher which - without a special AI-y algorithm - isn't going to yield true higher res.
Re:Responsive images
by onli on Saturday June 12, 2021 @12:14PM
(#27485420)
I have definitely seen that happen with the PHP blog engine that runs my blog, either with the GD image functions or with the imagemagick integration. Probably something like: Take an optimized image, like an indexed png, load it as raw image data, scale it down, save it in the same format but not optimized. The Wordpress code looks similar.
Re:Responsive images
by superfad on Saturday June 12, 2021 @12:49PM
(#27485660)
I've had this happen when uploading a highly optimized image (manually optimized with Squoosh) 2560px wide, then WP generating a 1920px wide version and the KB was larger. I believe I was using the free version of Smush at the time and had to change. Now using reSmush.it.
Re:Responsive images
by genghizkhan on Saturday June 12, 2021 @04:11AM
(#27482635)
Ghost (https://ghost.org/) does this automatically. They used to do it for featured images till v3, v4 takes this up a notch and automatically creates different sized images for every image in your blog post. It's extremely nifty and convenient.
Re:Responsive images
by tyingq on Saturday June 12, 2021 @08:32AM
(#27484013)
A fair amount of old php shopping cart software has done this for ages. Not for responsive design, but because they need thumbnails for category/search pages, normal images for a product page, and zoomed in photos for user detail clicks, etc. Typically, there's an imagemajick script or similar that's used on "product photo" upload.
Re:Responsive images
by Santosh83 on Saturday June 12, 2021 @05:05AM
(#27482933)
On large monitors, browsers are still picking the image tagged as 1x, and not the 2x or 3x versions, because the DPI of the monitor is 1x, but since the screen dimensions are large, the 1x image becomes pixelated or just too small.
Re:Responsive images
by bruce343434 on Saturday June 12, 2021 @05:08AM
(#27482948)
I can't really take a blog post seriously that claims to introduce responsive design, yet still uses pixel defined sizes like it's 2005. 1200px is nothing on a 4k monitor.
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.
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.
Re:Responsive images
by bruce343434 on Saturday June 12, 2021 @01:06PM
(#27485809)
What accessibility issues? that a _blind_ person might not _see_ that it's an image? Who really cares? And don't just go "oh bruce you're a bad guy you don't care about aria for blind people" but actually think about it. Images on the web are of 0 value to blind people. If it's really important to your article, add a subscript to the image. (which a screenreader will gladly read)
Re:Responsive images
by leephillips on Saturday June 12, 2021 @08:29AM
(#27483992)
Pixel in CSS is a CSS pixel, which your browser will translate to about 1/96 inches. So 1200px is the same physical length on an old 72dpi screen, a 4k monitor, or the quark-scale resolution displays of the future.
Re:Responsive images
by bruce343434 on Saturday June 12, 2021 @01:03PM
(#27485795)
I don't buy it. Old websites that have handcrafted tables, px-perfect to fit fullscreen on a vga monitor look really, really narrow and small on my screen.
Re:Responsive images
by leephillips on Saturday June 12, 2021 @01:12PM
(#27485857)
Someone in this thread quoted the CSS spec. You don’t have to “buy it”. A CSS pixel is a unit of length, like cm. It’s not a pixel. Of course that’s confusing. It’s supposed to be. It’s CSS.
Re:Responsive images
by bruce343434 on Saturday June 12, 2021 @06:06PM
(#27487799)
I get that but then perhaps my browser doesn't implement the spec correctly. Because I know what I see. Tiny pages with tiny text that would have looked fine on my 4:3 crt emac years ago.
Re:Responsive images
by leephillips on Saturday June 12, 2021 @06:13PM
(#27487841)
There are more things that come in to play, such as the resolution that X11 thinks your display has. Just zoom the page in. What’s important is the relative sizes of things on the page, not how big the page looks.
Re:Responsive images
by ghusbands on Saturday June 12, 2021 @10:29AM
(#27484734)
CSS px are not screen pixels. From the spec:
"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]
Re:Responsive images
by bruce343434 on Saturday June 12, 2021 @01:02PM
(#27485785)
I don't buy it. Old websites that have handcrafted tables, px-perfect to fit fullscreen on a vga monitor look really, really narrow and small on my screen.
Re:Responsive images
by innocenat on Saturday June 12, 2021 @06:30AM
(#27483391)
Doesn't CSS pixel scale based on your monitor scale setting? 1200px on a 4k monitor with 2x scaling ought to be roughly the same size as 1200px on FHD monitor with 1x scaling. Unless you are talking about source image, then it's intrinsics size.
Re:Responsive images
by bruce343434 on Saturday June 12, 2021 @01:05PM
(#27485802)
I don't buy it. Old websites that have handcrafted tables, px-perfect to fit fullscreen on a vga monitor look really, really narrow and small on my screen.
Re:Responsive images
by rhdunn on Saturday June 12, 2021 @05:35AM
(#27483084)
If you are using CSS, you will still have CSS media queries to say "load an image of this size when on a device with this maximum/minimum size" so you can send smaller sized images to devices with smaller screens.
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.
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].
[1] https://darekkay.com/blog/avif-images/
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.
https://gutshaeuser-ostpreussen.de/
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.
https://ericportis.com/posts/2014/srcset-sizes/
"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]
[1] https://www.w3.org/TR/css-values-3/#absolute-lengths
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.