How to use picture element for sharp images on mobile - html

Picture element is getting widely and quickly spread (http://caniuse.com/#search=picture), and I think it is a great way to avoid serving oversized/undersized pictures, specially when you want to display the same picture on mobile and desktop at 100% of the viewport width.
That can be solved like this:
<img
srcset="large.jpg 1920w,
medium.jpg 720w,
small.jpg 360w"
src="medium.jpg">
This allows the browser to be clever and decide which picture to load, but I find a problem with this approach: many mobile devices have a pixel density of 2 or more! Therefore when displaying it for 360w we would actually need the medium image if we want that image to look sharp. It could be done like this:
<picture>
<source srcset="http://goo.gl/LsuU9t" media="(min-width: 720px)">
<source srcset="http://goo.gl/LsuU9t" media="(min-width: 360px and min-resolution: 2dppx)">
<img src="http://goo.gl/LsuU9t">
</picture>
The problem here, in my opinion, is that this can grow as much as screen resolution grows and we lose the benefits of browser cleverly deciding the best option.
So, my question is if there is a halfway point between the two, so I can still separate between html and css.

The browser takes the pixel density into account when selecting an image. So a device with 360 CSS px wide viewport and a 2x pixel density would select medium.jpg. This is exactly what the w descriptor and the sizes attribute are designed to solve! Don't use picture here.
Also see https://ericportis.com/posts/2014/srcset-sizes/

Related

Why are the "srcset" and "sizes" attributes in the "img" element not working the way they should?

I am struggling to understand the srcset and sizes attributes in the <img> tag.
First of all, why is my code not working?
<img src="orange.jpg" alt="orange" srcset="coffee.jpg 600w, mycat.jpg 800w" sizes="(max-width:500px) 600px, 800px">
When i run this code, the mycat.jpg image loads regardless of how much i shrink the browser. Why?
I thought this code is supposed to mean that, if the viewport is up to 500px, then the 600px image should load, which is the coffee image, and if there isn't one, then the 800px image should load, which is the mycat image. So why is the mycat image loading regardless of the viewport?
Also, if the browser chooses which srcset image to load depending on the proximity of the sizes, then in what case does the src image (orange) loads?
Also, what happens if i add a wrong number for the resolution size of each srcset image? In my example, I've described coffee image as 600w and mycat image as 800w. What if these numbers are wrong?
Another thing I struggle to understand is, why is the sizes attribute being used here for adding a media condition? Isn't that what the media attribute is for?
The explanation given in mozilla.developers.org and other websites is atrocious. Please do not copy-paste any external sources purporting to explain this. They do not. I've seen them all.
Your code is not working because your code is incorrect because if you wanna put srcset attribute then you have to put it inside source tag which should be inside picture tag tag. Try writing the code attached below.
<!DOCTYPE html>
<html>
<head>
<title>srecset attribute</title>
</head>
<body>
<picture>
<source media="(min-width:800px)" srcset="mycat.jpg">
<source media="(min-width:600px)" srcset="coffee.jpg">
<img src="orange.jpg" alt="orange" style="width:auto;">
</picture>
</body>
</html>
In the above code if the screen resolution/size is more than 800px then mycat.jpg will be displayed.
If screen resolution/size is between 600px to 800px then coffee.jpg will be displayed.
And If screen resolution/size is less than 600px then orange.jpg will be displayed.
And if this doesn't work comment your issue, I will try my best to help you.
you have to put the image and sources inside a picture tag.
<picture>
<source srcset="coffee.jpg 600w" sizes="(max-width:500px)">
<source srcset="mycat.jpg 800w" sizes="(max-width:600px)">
<img src="orange.jpg" alt="orange">
</picture>
When browsers evaluate srcset, they take more than the sizes attribute into account. While I'm not sure the full list of things they consider, I know they also consider screen pixel density.
In your example, if the browser detects a 2x or higher pixel density, it would attempt to load a 1200px image to fulfill the 600px size. Since no such size exists, it uses the largest image available: mycat.jpg.

HTML5 srcset and sizes

<img src="media/640x320_image.jpg" srcset="media/640x320_image.jpg 320w, media/640x1280_image.jpg 768w" sizes="(min-width:768px) 768px, 320px">
What is wrong with the srcset and sizes above? The 640x1280_image.jpg always shows, when I make my window small it doesn't change.
I don't understand media/640x1280_image.jpg 768w. Do you really use a 640px wide image, but tell the browser it is 768px wide?
It breaks everything in the srcset algorithm, for sure.
It looks like you want to use Art Direction to have images of different proportions based on the viewport width.
If this is what you want, you need to use <picture>, because srcset alone doesn't provide this.

Responsive img/srcset/sizes: Different jpg quality depending on device pixel density?

I am looking for a responsive image strategy that allows to serve different jpg quality based on the device pixel density.
On a small screen with high resolution, I would serve a low-quality but high-resolution jpg. On a big screen with low pixel density, I would serve a high-quality jpg, ideally matching the device resolution.
QUESTION:
Is this somehow possible with <img srcset=".." sizes=".." />?
Background / scenario
Different original images with different original dimensions.
Different image display contexts: As a gallery thumbnail, embedded in a blog post, in a modal box, full screen..
Responsive layout, with media queries that change the display size of those images, not necessarily proportional.
E.g. a what is displayed as a 100px thumbnail on desktop, might be displayed in full width on mobile.
High-resolution or "Retina" devices, with a resolution multiplier. On these I want many pixels, but low file size.
Solutions I'm considering
I think the promising approach for this is <img srcset=".." sizes=".."/>.
However, I am wondering if or how I should combine the x-descriptor and the w-descriptor.
The x-descriptor specifies a relative size. But relative to what? Both the original image size and the layout width of the <img> can vary between contexts and between viewports. The viewport reports a width for the media queries, but the actual pixel width can be 2x or 3x the reported viewport width, thanks to retina displays.
The w-descriptor specifies an absolute size. This sounds way better for image contexts that could be in thumbnail size on desktop, and full width on mobile - or vice versa.
Questions / Related
How could I serve different jpg quality depending on the pixel density on the device? (question as above)
Related question: Do srcset and sizes refer to device pixels or layout pixels?
You can do something like this
<picture>
<source media="(min-resolution: 1.5dppx)"
srcset="low-quality-high-res.jpg 2x">
<img src="high-quality-low-res.jpg" ...>
</picture>
In practice you probably want to have multiple sizes for each quality:
<picture>
<source media="(min-resolution: 1.5dppx)"
srcset="lq-500w.jpg 500w, lq-1000w.jpg 1000w"
sizes="100vw">
<img src="hq-250w.jpg"
srcset="hq-250w.jpg 250w, hq-500w.jpg 500w"
sizes="100vw" ...>
</picture>
(And change sizes as appropriate depending on context.)

Understanding srcset width values

I'm trying to understand how srcset width values work, but the basic example I have is throwing me off.
Given the code below, I expect the large image to display when the viewport is > 600px. However, it actually changes at 784px. I'm not sure why this is.
<!-- image changes to large variant at 784px instead of the expected 1024px -->
<img
src="small.jpg"
srcset="small.jpg 600w,
large.jpg 1024w"
alt="A test image">
Currently Chrome uses a geometric mean to choose between two image candidates. So it still uses the 600 image because 1024 is too big and therefore switches.
In an upcoming release Chrome will always switch to the higher image, if you have a low density device. On other devices Chrome will still use a a median.

What is an srcset attribute in IMG tag and how to use it?

I want to know how could I start using the HTML srcset img attribute in my mobile apps. Or Is there any other jQuery plugin which helps me to solve image resolution problem.
<img srcset="banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x" alt="Banner Image" />
In short, Srcset is a new attribute which allows you to specify different kind of images for different screen-sizes/orientation/display-types. The usage is really simple, you just provide a lot of different images separating them with a comma like this: <img src="image.jpg" alt="image" srcset="<img> <descriptor>, ..., <img_n> <descriptor_n>">. Here is an example: srcset="image.jpg 160w, image2.jpg 320w, image3.jpg 2x"
This is a longer answer which explains things in more details.
Difference between srcset and picture. Both srcset and picture does approximately the same things, but there is a subtle difference: picture dictates what image the browser should use, whereas srcset gives the browser a choice. A lot of things can be used to select this choice like viewport size, users preferences, network condition and so on. The support for srcset is pretty good and almost all current browsers more or less support it. Situation with a picture element is a little bit worse.
Descriptors are just a way to show what kind of image is hidden behind the resource. There are various kinds of descriptors:
density descriptor. srcset="image.jpg, image-2X.jpg 2x"
The display density values—the 1x, 2x, etc.—are referred to as display density descriptors. If a display density descriptor isn’t provided, it is assumed to be 1x. Good variant to target retina displays.
width descriptor. srcset="image-240.jpg 240w, image-640.jpg 640w". I am sure this is self explanatory. The only problem is that by itself width descriptor is not really helpful. Why? read here
size descriptor, which only makes sense if you use width descriptor. srcset="image-160.jpg 160w, image-320.jpg 320w, image-640.jpg 640w, image-1280.jpg 1280w" sizes="(max-width: 480px) 100vw, (max-width: 900px) 33vw, 254px">. The instructions for the browser would look like this: (max-width: 480px) 100vw — if the viewport is 480 pixels wide or smaller, the image will be 100% of the viewport width. (max-width: 900px) 33vw — if the viewport is 480 pixels wide or smaller, this rule will never be reached because of the previous media condition. And 254px is when there is no media condition listed, the length is assumed to be a default value used when none of the other media conditions are met.
Just for completeness will add here that there is an image-set() attribute for a background image in CSS and some other helpful link here
Here is a detailed guide on srcset along with code samples.
srcset allows you to define a list of different image resources along with size information so that browser can pick the most appropriate image based on the actual device’s resolution.
Each comma-separated item in srcset has:
Image URL, e.g. http://ik.imagekit.io/demo/default-image.jpg or relative path /demo/default-image.jpg
An empty space
The actual width of the image or display density:
Either using display density descriptor, for example, 1.5x, 2x etc.
Or, using width descriptors, for example, 450w. This is the width of the image in pixels.
Using display density descriptor
The syntax for display density descriptors is straightforward. srcset provides a comma-separated list of image resources along with display density it should be used, for example1x, 2x etc.
<img src="image.jpg"
srcset="image.jpg,
image_2x.jpg 2x"
/>
Live demo - https://imagekitio.github.io/responsive-images-guide/srcset-density.html.
Using width descriptor
The syntax is similar to the display density descriptor, but instead of display density values, we provide the actual width of the image.
<img src="image.jpg"
srcset="small.jpg 300w,
medium.jpg 600w,
large.jpg 900w"
/>
This lets the browser pick the best image
Using width descriptor allows the browser to pick the best candidate from srcset based on the actual width needed to render that image on that particular display at runtime.
Note that display pixel density is also taken into account by the browser while calculating the required width. 😎
For example, assuming an image takes up the whole viewport width - On a 300px wide screen with DPR 2, the browser will pick medium.jpg because it needs a 300x2=600px wide image. On a 300px wide screen with DPR value 3, the browser will select large.jpg because it needs a 300x3=900px wide image.
Demo - srcset with width descriptor
Let see this in action with a live demo - https://imagekitio.github.io/responsive-images-guide/srcset-width.html.
Here is a good article on the srcset attribute and how to use it. srcet allows you to declare a set of images to be displayed on different viewport sizes. You just have to save and image at different resolutions e.g. banner-phone-HD.jpeg would be the highest resolution.
Exmaple:
<img alt="my awesome image"
src="banner.jpeg"
srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">
The above would serve banner-phone.jpeg to devices with viewport width under 640px, banner-phone-HD.jpeg to small screen high DPI devices, banner-HD.jpeg to high DPI devices with screens greater than 640px, and banner.jpeg to everything else.
There are also other methods like CSS media queries you can use to produce the same effect.
I am not aware of any JQuery plugins which would help with this.