Responsive image, srcset and sizes - html

I'm starting to use responsive image and I have a small doubt.
I have an icon. This icon on my website has always two sizes: a small version, 74 pixel wide and a large versione, 94 pixel wide.
<img alt="Sezione Gino" style="background-color: #dd0505" srcset="https://website.imgix.net/system/uploads/section/icon/1/immuni_t.jpg?ixlib=rails-4.0.0&w=94&h=72&fit=crop&sizes=94px&auto=format%2Ccompress&dpr=1&q=75 1x,
https://website.imgix.net/system/uploads/section/icon/1/immuni_t.jpg?ixlib=rails-4.0.0&w=94&h=72&fit=crop&sizes=94px&auto=format%2Ccompress&dpr=2&q=50 2x,
https://website.imgix.net/system/uploads/section/icon/1/immuni_t.jpg?ixlib=rails-4.0.0&w=94&h=72&fit=crop&sizes=94px&auto=format%2Ccompress&dpr=3&q=35 3x,
https://website.imgix.net/system/uploads/section/icon/1/immuni_t.jpg?ixlib=rails-4.0.0&w=94&h=72&fit=crop&sizes=94px&auto=format%2Ccompress&dpr=4&q=23 4x,
https://website.imgix.net/system/uploads/section/icon/1/immuni_t.jpg?ixlib=rails-4.0.0&w=94&h=72&fit=crop&sizes=94px&auto=format%2Ccompress&dpr=5&q=20 5x" sizes="94px" src="https://website.imgix.net/system/uploads/section/icon/1/immuni_t.jpg?ixlib=rails-4.0.0&w=94&h=72&fit=crop&sizes=94px&auto=format%2Ccompress">
I created using imgix this srcset for the large icon.
I check the images and they are resized in the right way, the 1x is the 94pixel wide, the 2x is 188 pixel wide.
I fixed the sizes of 94 because in the large version the image is always 94px.
Now my question: for the 74 pixel version, so the small icona, I have to recreate the set using 74px for size?

Yes, you would have to recreate the set.
If they're the same icon, you could just copy and paste and replace w=94 with w=74, though you may also have to adjust the height so the image isn't distorted.

Related

High-quality hero images get blurry when viewed at smaller sizes

I've been trying to fix an issue where the full-width hero images on my Wordpress website appear blurry on some mobile devices, and in the process I've noticed that this seems to be triggered only at smaller sizes.
The images I'm using are 1920 x 1080 pixels.
Between a width of 1920px to 1024px the images look high-quality and unchanged as far as I can tell, but using Firefox's Responsive Design Mode, I've established that the smaller the image renders the more progressively blurrier (i.e. pixellated) it becomes.
If the browser window is resized to a width of 1023px or less, it becomes a little blurry, whereby setting the DPR setting to 2 restores it to the original quality.
If the browser window is resized to a width of 512px or less, the image becomes very blurry, and setting the DPR to 3 restores it to the original quality.
What's going on here? I understand that the images aren't Retina-optimised, but if this was the actual cause, wouldn't the problem be reversed - wouldn't it be the larger image size that would render blurry? Shouldn't the smallest image render at a high DPI considering it's being displayed at a size of 512px and the source image is much less than double (2x) the 1920px source image?
Would really appreciate some help figuring this out as I've been struggling with it for a few days and it's very hard to test against and debug.
A HiDPI image is really just one that's larger than the display size but crushed into a smaller physical space.
For example if your 1x image is 500px x 500px, then a 2x image would be 1000px x 1000px and 3x would be 1500px x 1500px. The HiDPI designation comes in because the device is able to display all those extra pixels in the same physical space as a normal screen.
So imagine a normal screen is 100px per 1 inch. So your 500px image would be 5in x 5in. The HiDPI screen might be 200px per 1 inch of screen so the 1000px image would still take up 5 inches.
Typically smaller images get blury on HiDPI displays because they're trying to "up res" something like a 500px x 500px image to a display size of 1500px x 1500px.
As for the problem you're experiencing, have you verified the issue on a real device not the FF emulator? Real devices are usually much better at that "up res" process and may not produce the same artifacts.

Correct way to resize srcset images

What is the correct way to resize srcset images? For example say I have an image that is 2000 x 1337. I resize it to 255 x 170. For 2x srcset should it be:
510 x 340 (based on current image)
510 x 339 (based on original image)
Edit
To clarify I want to know how srcset works. For example if I use the 510 x 339 image (technically more correct dimensions based on the original) for 2x will the browser "create" a 510 x 340 container (current dimensions x 2) and then resize the 510 x 339 image to fit inside it?
<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="yah">
With srcset, the browser does the work of figuring out which image is best
In the simple example above, all we're doing is telling the browser about some images that we have available and what size they are. The browser then does all the work figuring out which one will be best.
Mat Marquis demonstrated this by showing how the browser approaches it with math. Say you're on a device with a screen width of 320px and is a 1x (non-retina) display. and the images you have are small.jpg (500px wide), medium.jpg (1000px wide), and large.jpg (2000px wide).
The browser goes:
Lemme do some quick math that nobody cares about except me.
500 / 320 = 1.5625
1000 / 320 = 3.125
2000 / 320 = 6.25
OK, so since I'm a 1x display, 1.5625 is the closest to what I need. It's a little high, but it's the best option compared to those other that are way too high.
Now another browser visits the site. It's also a 320px display but it's a retina (2x) display. That browser does the same math, only then goes:
OK, so since I'm a 2x display, I'm going to throw out that 1.5625 image because it's too low for me and might look bad. I'm going to use the 3.125 image.
See how that's already useful? You're letting the browser do the work of figuring out what's best for it rather than you trying to figure it out
To what you asked specifically that change in one or two pixel does
not matter .What you should be looking at is basically for higher
pixel density the large image will be loaded
and for 2X just use double the width 100% percent precision is not
required
and for getting the width you want you can use the w descriptor:
<img src="images/space-needle.jpg"
srcset="images/space-needle.jpg 200w, images/space-needle-2x.jpg 400w,
images/space-needle-hd.jpg 600w">
The actual implementation where you’d want a different size image (different height, width) on different screen sizes is accomplished by using sizes attribute along with the w descriptor of srcset attribute. Let’s again learn through a couple of examples:
Example 1
Say you want the image to be viewed in half of the viewport width. You’ll type:
<img src="images/space-needle.jpg" sizes="50vw"
srcset="images/space-needle.jpg 200w, images/space-needle-2x.jpg 400w,
images/space-needle-hd.jpg 600w">
The browser will now decide which image to download based on the browser width and the device pixel ratio. For example:
If the browser width is 500 CSS pixels, the image will be displayed 250px wide (because of 50vw). Now, this is equivalent to specifying:
srcset="images/space-needle.jpg 0.8x, images/space-needle-2x.jpg 1.6x,
images/space-needle-hd.jpg 2.4x"
So, for a 1.5x display, images/space-needle-2x.jpg will be downloaded by a browser, since it gives a device-pixel ratio of 1.6x (which is most suitable for a 1.5x display).
EDIT 1:-
And what you are actually looking for is rather than srcset.You dont want your images to be blurred in resize or what you call responsive images should maintain its orginal quality and do not blurr.
I have added the Q&A from SO regardiing the same issue here
which explains the use image-rendering css property
EDIT 2:-
img{
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
-ms-interpolation-mode: nearest-neighbor;
image-rendering: pixelated;
}
The issue regarding image rendering on scaling can be addressed using the image rendering css proprety upto and extant try it out on the scaled image .Documentation is given below.
On the question whether browser will change the size of image by adjusting the image to fit to the container size answer is ie changing from 539 to 540 :-
NO it wont srcset depending upon the constraints used only takes the best picture suited for that display wrt pixel density or screen size which ever may be the given contraint.Rest depends upon the css .
Simple example without srcset
https://jsfiddle.net/f03hwb7p/1/
https://drafts.csswg.org/css-images-3/#the-image-rendering
https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering
Image downscaling with CSS … Images are blurry in several Browsers
http://heygrady.com/blog/2012/05/25/responsive-images-without-javascript/
External Reference 1
External Reference 2
Orginal Article from where this paragraph was taken
W3c examples adn explanation
The correct way is option 1: 510 x 340 (based on current image)
If you use 510 x 339 (based on original image) the browser will just stretch it until it fits inside the 2x box.
The image you use must have dimensions divisible by 2 (for 2x) or 3 (for 3x) otherwise the browser will resize it even if you don't have a width or height set.
Test 1 - 600x300 (3x) image inside 200x200 img container on Chrome, Nexus 5
<img src='200x200.png' srcset='600x300.png 3x' width="200" height="200">
This image originally contains a circle, as you can see the browser stretches the image to fill the 200 x 200 container.
Test 2 - 600x600 (3x) vs 600x599 (3x) image inside 200x200 img container on Chrome, Nexus 5
<img src='200x200.png' srcset='600x600.png 3x' width="200" height="200">
<img src='200x200.png' srcset='600x599.png 3x' width="200" height="200">
Checking just in case the browser has some smarts to leave images that are 1px different alone (because it is possible that these images would be the "correct" dimensions). Doesn't seem to.
If your image container is fixed to 255 x 170, do the math for
(2x = *2) = (CurrentImageSize * 2 = x)
Ratio is calculating lowest to high (Ascending)
e.g.
iPhone: 57 x 57 (1x)
Retina iPhone: 114 x 114 (2x)
iPad: 72 x 72 (3x)
Retina iPad: 144 x 144 (4x)
Technically: if (1x = 57) then (2x = 114)
Demo Example: https://webkit.org/demos/srcset/

Why SVG image gets ugly resize with CSS (Chrome, Firefox tested)

I can reproduce this issue in both Chrome and Firefox.
This is SVG image in question:
https://www.iconfinder.com/icons/284101/editor_hambuger_list_menu_view_icon#size=512
And this is the minimum code which reproduces the problem:
<img
style="width: 15px; vertical-align: middle;"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxMnB4IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAyMiAxMiIgd2lkdGg9IjIycHgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48dGl0bGUvPjxkZWZzPjxwYXRoIGQ9Ik0wLjUwMDgzNjEzNCwwIEMwLjIyNDIzMTk3NSwwIDAsMC4yMTQwMzUwMzQgMCwwLjUwNDY4NDQ0OCBMMCwxLjQ5NTMxNTU1IEMwLDEuNzc0MDQ1MDggMC4yMTc3NDE3MjgsMiAwLjUwMDgzNjEzNCwyIEwyMS40OTkxNjM5LDIgQzIxLjc3NTc2OCwyIDIyLDEuNzg1OTY0OTcgMjIsMS40OTUzMTU1NSBMMjIsMC41MDQ2ODQ0NDggQzIyLDAuMjI1OTU0OTI0IDIxLjc4MjI1ODMsMCAyMS40OTkxNjM5LDAgTDAuNTAwODM2MTM0LDAgWiBNMC41MDA4MzYxMzQsNSBDMC4yMjQyMzE5NzUsNSAwLDUuMjE0MDM1MDMgMCw1LjUwNDY4NDQ1IEwwLDYuNDk1MzE1NTUgQzAsNi43NzQwNDUwOCAwLjIxNzc0MTcyOCw3IDAuNTAwODM2MTM0LDcgTDIxLjQ5OTE2MzksNyBDMjEuNzc1NzY4LDcgMjIsNi43ODU5NjQ5NyAyMiw2LjQ5NTMxNTU1IEwyMiw1LjUwNDY4NDQ1IEMyMiw1LjIyNTk1NDkyIDIxLjc4MjI1ODMsNSAyMS40OTkxNjM5LDUgTDAuNTAwODM2MTM0LDUgWiBNMC41MDA4MzYxMzQsMTAgQzAuMjI0MjMxOTc1LDEwIDAsMTAuMjE0MDM1IDAsMTAuNTA0Njg0NCBMMCwxMS40OTUzMTU2IEMwLDExLjc3NDA0NTEgMC4yMTc3NDE3MjgsMTIgMC41MDA4MzYxMzQsMTIgTDIxLjQ5OTE2MzksMTIgQzIxLjc3NTc2OCwxMiAyMiwxMS43ODU5NjUgMjIsMTEuNDk1MzE1NiBMMjIsMTAuNTA0Njg0NCBDMjIsMTAuMjI1OTU0OSAyMS43ODIyNTgzLDEwIDIxLjQ5OTE2MzksMTAgTDAuNTAwODM2MTM0LDEwIFoiIGlkPSJwYXRoLTEiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBpZD0ibWl1IiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSI+PGcgaWQ9ImVkaXRvcl9saXN0X3ZpZXdfaGFtYnVnZXJfbWVudV9nbHlwaCI+PHVzZSBmaWxsPSIjMDAwMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHhsaW5rOmhyZWY9IiNwYXRoLTEiLz48dXNlIGZpbGw9Im5vbmUiIHhsaW5rOmhyZWY9IiNwYXRoLTEiLz48L2c+PC9nPjwvc3ZnPg==" /> Menu
You can play with it and see it in action at:
http://jsfiddle.net/adamovic/s3dZ2/1/
Anyone has an idea why this Scalable Vector Graphics gets resize where lines becomes unproportional and also any idea how to fix this good?
BTW, in production I'm resizing this image to 1EM, to appear next to text "Menu" but to reproduce this issue it is the simplest way.
UPDATE: Updated example from 11.5px to 15px, reproducing same issue.
In production I'm using width: 1EM; or something like that for responsive design, any idea how to responsive scale this image so that lines are proportional?
Maybe some fix like min-width and max-width could work, but I couldn't make it work ever with some mozilla image specific commands.
At 11.5 pixels in with the height of the image should be 6.3 pixels. Of those, 1.1 pixels should be the height of each black line, and 1.5 pixels the height of each white line. And on top of that the browser resizes the picture to 6 pixels height.
If the image had 1 pixels for each line (both white and black) and the size multiple of 5, it would look great.
Later edit
In the given picture a black line is 16.67% of image size(all lines reprezent 50%) and a white line is 25%. So... for a height of 8 pixels the a black line has a height of 1.3 pixels and a a white line 2 pixels. On paper the smallest image that looks good and unaltered has 2 pixels for black line and 3 for the white line, meaning an image with 12 pixels height.
Basically if one pixel has to share both white and black lines the browser will create a shade of gray that is the average of the two as it can only display one color.
EX: a pixel has to show 0.67 white(#FFFFFF or 255,255,255) and 0.33(#000000 or 0,0,0) black:
0.67*255 + 0.33*0 = 170.85 (aproximatly 171) so the color displayed is (#ABABAB or 171,171,171)
Theoretically, SVG image is infinitely scalable. In practice however, the screen has limited resolutions, so if you scale an SVG too small, it won't look very good due to pixelations.
To avoid this problem, you need to set a minimum size for the icon at the point where it still looks good. High quality small-sized vector iconsets would usually be designed to have in such a way that their major lines lie in a grid of integer proportion for many different sizes, so that they will look crisp on different sizes; some icon designers might also provide a separately-drawn raster icons for low resolutions.
Inferring from the size declaration in the SVG, the icon you linked seems to have been designed for 22x12 or multiples of it.
On small sizes, you probably should also use media-queries so that small icons are scaled in a step-ladder of sizes with sizes that are known to look good rather than strictly depending on the viewport size.

DPI and Retina image explanation

I've been reading about the #2x images being only image that are twice as big as regular image, but do we have to change the DPI to make the quality better or we only need an image that is twice as big ? I don't understand why would a twice as big image of the same quality would be better? Thanks alot
Don't worry about DPI it doesn't matter for screens, but to answer your question making an image twice the size with the same quality would have a much higher pixel density than the original, therefore the pixels rendered will be much sharper and well defined.
For example:
Original image: 300px x 300px = 90,000 pixels
Retina image (same quality): 600px x 600px = 360,000 pixels
Now when the browser renders the Retina image, it still renders it in the same 300px by 300px space as the original image. This means that there are 360,000 pixels in this image instead of the 90,000 pixels before. Now there are lots more pixels to render the same image, so the image is going to look more defined.
For screen, DPI doesn't exist. The raw basic you need to understand is pixel count. You can have a 100px x 100px image that's 1 DPI or 100,000,000 DPI, it makes no difference.
If you really want to learn some more, take a look at http://en.wikipedia.org/wiki/Pixel_density
But for screen output, you can just ignore DPI.

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.