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

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.

Related

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.

Auto-width image with `srcset` attribute

Say I have the following image:
<img src="//picsum.photos/100" srcset="//picsum.photos/100 100w">
It appears that the sizes attribute I have not included defaults to 100vw, hence the small image is upscaled to the width of the viewport.
What do I do if I don't want this behavior, but instead want the image to default to its intrinsic size?
I would expect that this image would default to 100px in width on a normal display, and 50px on a 2x (retina) display.
If I specify my own sizes attribute of 100px, this doesn't solve the problem of displaying it at 50px when on a retina display.
The reason I need this behavior is because in my system users are allowed to upload images of any size and place them on a page, and I am generating an srcset with multiple steps up to the max size of their image, and I need a way for the image to display at the correct width given the size of the image and the pixel density of the user's screen.
Can this behavior for auto-width images be achieved using srcset?
In my research I've found this article which addresses the issue directly. The author recommends adding the width attribute with the maximum size of the image to revert what the sizes attribute does to the image's intrinsic size. However, he does not address how to make this work with differing pixel densities.
Unfortunately it seems there isn't a way to have an image with srcset default to its natural size, taking DPR into account. The sizes attribute, which defaults to 100vw if not set on an image with srcset, redefines the image's intrinsic width, and there doesn't seem to be a way to reset it without providing an explicit width yourself.
In my specific situation I discovered that we were already storing the user's DPR in a cookie, so server-side I've started setting the width attribute on images to the max width of the image divided by the user's DPR. This prevents the image from being displayed larger than the original size, and ensures that the image is sized appropriately for devices with high pixel densities.
Of course, you'll probably want to combine this with max-width: 100%; in your CSS to prevent the image from displaying larger than its container.
Example solution:
<!-- Width generated server-side for standard displays: -->
<img src="//picsum.photos/100" srcset="//picsum.photos/100 100w" width=100>
<!-- Width generated server-side for displays with a DPR of 2: -->
<img src="//picsum.photos/100" srcset="//picsum.photos/100 100w" width=50>

Image resized by HTML way sharper than by PhotoShop

I apologize if this is not the correct community to ask, but I believe this has to do with HTML so I'm asking here.
I need a small banner with credit card icons (21px high).
I made it in PS and resized it to 21px height (auto width), but I wasn't satisfied with the sharpness.
I now load the full image in HTML and using height and width image tag attributes resize it to the same size I did in PS, but the result is much better.
1) Resized with HTML
2) Resized with PS
Chrome developer tool shows that both of the images are the same dimensions.
Why is there such a difference?
Browsers just display it as it would be 21px high, but higher dpi screens may use the full image to make it sharper. As in the screenshot you shared, both rows are actually ~90px high. Height doesn't actually resize the image itself, it just stretchs it to a smaller area.
Tip: Downsizing a large image with the height and width attributes forces a user to download the large image (even if it looks small on the page). To avoid this, rescale the image with a program before using it on a page.
From w3schools

Img srcset and sizes attributes

I'm trying to make a simple website with img tag, that will use the new srcset attribute. The main idea is to change the image (src) depending on the screen resolution.
Working example
The problem is with the sizes. As you can see, now it is 100vw, but it doesn't work correctly. For me, it resize img to about 80% of the screen, not 100%.
The best thing is, that when I write in CSS for img tag width: 100vw, it will resize to 100% of the screen.
Can someone help me with that? Maybe I'm doing something wrong?
The image is 1152 pixels wide, but you tell the browser it is 1500 pixels wide (1500w).
The browser then determines the image's density based on what you told it, and corrects the image's intrinsic dimensions accordingly, but since it used the wrong value for the density calculations, the image occupies 76.8% of the viewport width rather than 100% of it.
To change that, you can provide the browser with a larger resource, or tell it that the resource is 1152w.

HTML/CSS: What should I use to define image height/width to make it resolution independent?

I've read all over the Internet that I should not define fonts (or anything) with absolute pixel height/width/size and instead, use EM ... so that on higher resolution displays, my web site can scale appropriately.
However, what do I use to define IMAGE height/width ... because images won't scale well (they look pixelated)
UPDATE:
To clarify, I'm not referring to page zoom. I'm referring to how to make my web application resolution independent so that it will look correct on higher DPI displays.
I know this question is a bit old, but want to put this out there for anybody who may come along later. When talking about mobile devices which have higher pixel densities, the mobile browsers will zoom the page in by an amount to make it appear as though the web page is not very small. Devices implement this zooming as per the CSS 2.1 specification.
For example, many devices today have a 1.5x pixel density ratio compared to desktop monitors. As a result, the mobile browser will zoom websites by about 150% to compensate for the extra pixels. The new retina display has a 2x pixel density ratio... and as such the browser zooms in websites by about 200%.
Point of the matter - developers should not have to worry about different resolution devices. If you wish for your images to show up clearly on high resolution devices, you will need a higher resolution image. You generally don't have to worry about 1.5x devices as the quality difference is negligible and not worth the effort. However, the new retina display causes some really blurry images, and as a result you should use 2x the image.
So for the following image, you would want to export a 600x400px image in order for the image to show up clearly on the new retina display:
<img src="photo.jpg" style="width:300px; height:200px" />
Font sizes should be set in em (or %) because if the user changes the text size in IE (View > Text Size), text set in px (or have a fixed size somewhere up the inheritance chain) won't be resized. (Other browsers have no problem resizing text set in px.) See How to size text using ems for more on this.
Images with px dimensions are not resized when the user changes text size; images with em dimensions are resized. So if an image's size should be relative to the text size (a rare case), then use em. Otherwise px dimensions is fine.
For page zoom (where the browser makes everything larger or smaller), it doesn't matter if dimensions (text or image) are defined using em or px.
Normally, I use em for most elements and exact pixels for images. Your images will not scale with everything else when the text size is adjusted, so you need to review how the page looks at different text sizes and adapt when required, but I find this a reasonable compromise (versus scaling the images that is).
Using em when resizing the text in IE, it becomes larger than it should when made larger, and smaller than it should when made smaller.
The solution that works in all browsers, is to set a default font-size in percent for the body element:
body {font-size:100%;}
h1 {font-size:2.5em;}
h2 {font-size:1.875em;}
p {font-size:0.875em;}
http://w3schools.com/css/css_font.asp
You can find a perfect example of image styling using px with source code here: http://w3schools.com/css/css_image_gallery.asp. The images scales perfectly with the text increasing or decreasing it.
see the solution of this page
http://nickcowie.com/2005/elastic-images/
HTML
<div class="imageholder">
<img src="/images/tim_underwood_rb2.jpg" class="vertimage43 floatleft">
<img src="/images/joe_smash1v.jpg" class="vertimage43 floatright">
</div>
CSS
.widecolumn .imageholder {
width:51.5em;}
.widecolumn .vertimage43 {
height:32em;
margin:0;
padding:0;
width:24em;}
It's not really possible to make a page resolution-independent when it comes to images.
You can use SVG for images, because vector graphics truly are indepent of DPI, but this won't work well for photos.
You can use high-resolution images and display them at smaller size. This way, when sized up, they look a lot better. On some browsers, the downscaled image won't look too bad.
This is an example page, http://www.cssplay.co.uk/menu/em_images it has high-res images that are sized with ems. On Opera with page zoom, the high res images retain their clarity at higher zoom levels.
For retina devices you can also have a second image twice the size and add #2x to the file name...
so if you have a 200px x 300px image called image.jpg you just put in another one that's 400px x 600px and name it image#2x.jpg and retina devices will display that instead.