Responsive image mapping does not work to scaled images - html

I use picturefill.js for responsive image feature. When I place original image without specifying height and width, image is shown in <picture> tag and pull up different size of same images according to screen size.
But when i specify height and width, responsive feature does not work. Image is loaded with <img> tag.
here is link

The documentation of the library explains you should manage the image size by using the sizes tag:
<img
sizes="(min-width: 40em) 80vw, 100vw"
srcset="examples/images/medium.jpg 375w,
examples/images/large.jpg 480w,
examples/images/extralarge.jpg 768w"
alt="…">
By defining a style with a width and height you are forcing the image to keep that aspect.
From the site:
The sizes syntax is used to define the spaces your image will occupy in your layout. srcset then defines a list of images and their inherent widths. This allows the browser to choose the smallest appropriate source for the size available in that part of the layout, rather than the viewport size alone.

Related

How does the browser determine which srcset image to load when no sizes attribute is present?

I have an image that gets displayed in various sizes on my website:
The website is responsive and the apparent image size is often the size of the browser, with some exceptions when the browser is very wide. So, the image's width can vary between 200 and over 1000 pixels.
We want the image to be displayed in native resolution on high-resolution devices (Retina).
So, our image is present in three resolutions, let's call them i1.png, i2.png and i3.png.
What I would like to do is just this:
<img src="i1.png" srcset="i1.png 420w, i2.png 840w, i3.png 1260w" />
In my opinion, the browser should have enough information to figure out which image it needs.
On a standard-resolution device (no retina screen), it just takes the width of the <img /> element and then loads the image that has a width higher or equal to the width of the element. E.g. if the image element is 600px wide, then it will load i2.png.
On a retina device, it would just multiply the width of the <img /> element with the device-pixel ratio. E.g. on a "2x" device, it would load i3.png for a 600px image, because 2 x 600 = 1200, so it would need the image with a width of 1260px.
It seems the browser indeed does something like that, but in some cases it would load the 840px image even though the 420px image would be enough.
What factors does the browser use to determine the size of the image to load?
Is it using CSS rules to determine the image's apparent width?
Or does it ignore CSS and just look at width and height attributes on the <img />, if present?
What if some parts of CSS are not yet loaded?
Crucial point: I do not want to use the sizes attribute, because I would need media queries for all possible combinations of device-pixel ratios and browser window widths. This should not be necessary, because as I said, the browser should have enough information.
I checked the Mozilla Docs about the topic, but they say that if sizes is omitted, then we need to use 2x descriptors (instead of 420w descriptors) in the srcset attribute. This is useless for my scenario: the goal is to have the browser find out which image to load, not just based on device-pixel ratio, but also based on responsiveness.
Seems that the browser does not respect any CSS to decide which image to load. After all, it is not clear which CSS files have already been loaded when the image starts loading.
Instead, it treats each image as if it was stretched to the full page width. If the screen is non-retina and 600px wide, it would load the next-higher image size (840px in the above example), regardless of the actual size that the image would occupy on the screen.
For retina screens, it would just multiply the required image width by the device-pixel ratio.

Responsive full-width images and srcset

I have a site where I want some full-width images (they'll be cropped vertically, for a parallax look). I want to I've read a bunch of articles on srcset and sizes and tried a few things, but I can't figure out (a) whether I need to use "sizes" at all, and (b) especially without sizes, how the browser will choose which image to load.
For concreteness, here's an image spec:
<img src="/images/full/2c8n.jpg" srcset="
/images/320/2c8n.jpg 320w,
/images/640/2c8n.jpg 640w,
/images/1024/2c8n.jpg 1024w,
/images/full/2c8n.jpg">
This is in a full-width container div so the image should go edge to edge.
I'd like it to load the smallest one on mobile and the largest one (the /images/full one) on big desktops, but that doesn't seem to be happening. I've seen that it's possible to use x style as well, but I'm not sure how I'd choose which image to use with each scale factor, if that's even the right way to do it. Any idea what I'm doing wrong and what's the proper way to do this?
The documentation is pretty unclear about the sizes attribute. What I've been able to determine is that it only affects what size to render the image, and NOT image selection. So, sizes="(max-width: 500px) 50vw, 100vw" tells the browser:
if the viewport is up to 500px wide, render the image at 50% of the viewport (50vw)
if the viewport is 501px or larger, render the image at 100% of the viewport (100vw)
For the srcset attribute, the browser takes a look at your list of images, guesses at what size the slot is it should fill and then chooses the next size up. So, edge to edge as per your requirement, this is how it would choose which file to use:
Viewport width up to 319px -> /images/320/2c8n.jpg
VW 320px to 639px -> /images/640/2c8n.jpg
VW 640 to 1023 -> /images/1024/2c8n.jpg
VW 1024 and larger -> /images/full/2c8n.jpg
I've also read, but haven't verified yet, that it uses the first image it finds that fits the requirements between the src and srcset tags. The order of the attributes may make a difference. Again, read but not verified.

How to use image srcset properly in HTML5

I have setup the following img srcset:
<img srcset="http://via.placeholder.com/320x150 320w,
http://via.placeholder.com/480x150 480w,
http://via.placeholder.com/800x150 800w"
src="http://via.placeholder.com/800x150"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
width="200" />
No matter how I set the width of the img, or how I resize the window, chrome always downloads and displays the 800px wide image. What gives? Adding sizes attribute also has no effect. I referenced this article.
Demo here: http://jsfiddle.net/7ek62m13/1/
You are using srcset the correct way. Srcset is for when you have big images and you have smaller formats on smaller devices. If you load the biggest image there is no need to load another smaller image (cause a srcset is meant for the same image). This results in when you open this code on your phone it will display the smallest image, but when you are on desktop it will open the regular image. If you upscale your browser again srcset will replace your image with a bigger image but it will never swap back to a lower image. I hope I made it a bit clearer.

Responsive images - srcset and sizes attribute - how to use both correctly: device-pixel-ratio-based and viewport-based selection together?

I have read about this problem quite often so far and it also occurs for my own projects. Here is an introduction of what I have found out so far about the srcset and the sizes attribte.
There are two different possibilities on how to use the srcset-attribute (source w3c: http://w3c.github.io/html/semantics-embedded-content.html#device-pixel-ratio):
Device-pixel-ratio-based selection when the rendered size of the image is fixed
This is a simple and reliable way to use srcset. You simply say: If the device-pixel ratio of the target devicer is bigger than x, display this image with the following higher resolution.
The x descriptor is not appropriate when the rendered size of the
image depends on the viewport width (viewport-based selection), but
can be used together with art direction.
Example:
<img src="/uploads/100-marie-lloyd.jpg"
srcset="/uploads/150-marie-lloyd.jpg 1.5x, /uploads/200-marie-lloyd.jpg 2x"
alt="" width="100" height="150">
Viewport-based selection
This method allows you to display different image sizes depending on the size of your viewport. This is the method you are primarily using within your example.
The srcset and sizes attributes can be used, using the w descriptor,
to provide multiple images that only vary in their size (the smaller
image is a scaled-down version of the bigger image).
Simple example:
<h1><img sizes="100vw" srcset="wolf-400.jpg 400w, wolf-800.jpg 800w, wolf-1600.jpg 1600w"
src="wolf-400.jpg" alt="The rad wolf"></h1>
One step further: Using the sizes attribute
The default for Viewport-based selection and srcset is, that the image always has 100% width (100vw). The sizes attribute is giving the great possibility to tell the browser, how the width of an image is at a certain screen width.
The sizes attribute sets up the layout breakpoints at 30em and 50em,
and declares the image sizes between these breakpoints to be 100vw,
50vw, or calc(33vw - 100px). These sizes do not necessarily have to
match up exactly with the actual image width as specified in the CSS.
The user agent will pick a width from the sizes attribute, using the
first item with a (the part in parentheses) that
evaluates to true, or using the last item (calc(33vw - 100px)) if they
all evaluate to false.
Example:
<img sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
srcset="swing-200.jpg 200w, swing-400.jpg 400w, swing-800.jpg 800w, swing-1600.jpg 1600w"
src="swing-400.jpg" alt="Kettlebell Swing">
Here is the challange where I would be really glad if someone could enlighten me
Can I rely on srcset that a Client always load the correct image? Or is the actually loaded image also depending on processing power and internet connection speed as some people stated? I had complaints about retina devices which load lower resolution images.
How can I use both: Device-pixel-ratio-based and viewport-based selection together? Because for each possible size in sizes, I may want to define a retina image with 200% size as well as a non-retina image.
And furthermore: Does it make sense to use different images within srcset for different viewport sizes or is this a misuse of the srcset attribute? If it is possible to combine device-pixel-ratio-based and viewport-based selection, this should also be possible.
Can I rely on srcset that a Client always load the correct image?
The answer is NO. Moreso, you can never know the dimension of the image the user will upload unless you want to check that with a Javascript code and then restrict the user to upload the right dimension. But that will not be too user friendly.
Again, You might want to implement an algorithm to always resize the image to the particular size you want without distorting the quality, so you don't have to pass different imageurl to the srcset and just use the src attr. This can be an advantage to users with slow internet connection.
Does it make sense to use different images within srcset for different viewport sizes or is this a misuse of the srcset attribute?
The point is how many device Viewport do you want to handle in all. If you specify different image sizes and dimension for different view port, you might not able to target all at once especially when a new device is available that you didn't handle as at the time you were developing.

How to use HTML img srcset in fluid layout?

I have a web page design where the layout size and image sizes are based on em's. For example:
<html style="width:50em; font-size:16pt">
<body>
<p>Lorem ipsum
<img src="..." style="float:right; width:20em">
</p>
</body>
</html>
Because the image size is specified in em's, it is always in lockstep with the text size. Unfortunately, we don't know how many CSS pixels wide an image is. We also don't know how many device pixels wide an image is, which depends on the size of an em, the magnification, etc.
The <img> srcset and sizes attributes appear to be nearly the solution I want. But I'm not sure if it applies to my situation here. I can generate multiple asset sizes, e.g. 320×240, 480×360, 640×480, etc.
I want the web browser to look at the content box for the <img> element, calculate how many device pixels wide it is, and download the most appropriate image from a list of alternatives. How can I do this?
Note: I did read about the srcset x syntax, but it doesn't seem to be the right tool.
Srcset is definitely a great way to approach this. You basically have a number of images you save out for multiple sizes, usually you'll want to have the image be the same width of the element if possible. Then you set the image that you want to use for each screen width.
<img src="image.jpg" alt="Name"
srcset="
/img-2400.jpg 2400w,
/img-1800.jpg 1800w,
/img-1200.jpg 1200w,
/img-900.jpg 900w,
/img-600.jpg 600w,
/img-400.jpg 400w"
sizes = "(min-width: 2400px) 900px,
(min-width: 1800px) 600px,
(min-width: 1200px) 500px,
(min-width: 900px) 500px,
(min-width: 600px) 600px,
400px" />
So /img-2400.jpg 2400w would use /img-2400.jpg when the screen is closest to 2400px wide.
In the sizes attribute, you can also specify if what the image size will be at certain screen sizes as it may not always be 100% of the width of the browser.
So (min-width: 2400px) 900px is telling the browser that when the window is at least 2400px wide, the image will be 900px wide on the screen. So that should be telling the browser to then grab /img-900.jpg when the window is 2400px wide since that image is set to 900w which is the closest to 900px (its exact).
You can still approximately calculate this if you are using em, by multiplying the em you are using by 16 (this may vary depending on browser settings or settings you impose in your css). So if you set your width of an image in css to be 20em, thats 16 * 20 = 320px.
When these are used in combination, modern browsers should be able to detect the best image to grab dependent on the screen size. See browser compatability for srcset here: https://caniuse.com/#search=srcset
Based on Eric Portis's article, this solves the problem:
<img style="width:20em" sizes="20em"
src="pic-1000.png"
srcset="
pic-150.png 150w,
pic-220.png 220w,
pic-330.png 330w,
pic-470.png 470w,
pic-680.png 680w,
pic-1000.png 1000w">
After the web page is loaded, if the most appropriate image changes for some reason (e.g. using zoom to change the device pixel ratio), then Firefox will always change the image to the most appropriate one at the moment. By contrast, Chrome seems to change the image if the new one is bigger, but won't change to a small image unless you reload the page - the image resolution is sticky upwards.