I have a lot of images on a page, a gallery. I want the images to stay sharp, so I don't do any browser scaling, I use the original dimensions of the image.
However, this works only when the browser zoom level is 100% . When I increase or decrease the zoom level, the quality of the images decrease.
Some clients actually have different zoom levels by default. I was wondering, how can you handle it and do we handle it at all ?
I think most of the other answers have missed the point: this isn't about overriding user preferences, it's about giving the best quality images in the common scenario of a user's device assigning more than one physical pixel for each CSS pixel aka "Reference pixel" in your image, resulting in the browser scaling up the image, making it pixelated and grainy.
My suggested solutions below, but first here are the four ways this can happen:
- Most rare: the user chooses to zoom in. Not such a big problem, since it's their choice.
- Surprisingly common: the user's browser is zoomed in by default. For example, many high pixel density Windows machines are zoomed to 125% or more by default, and Firefox recently (confusingly!) made it so in these cases it tells users they are zoomed to 100% when they're actually zoomed to 125%, leaving them scratching their heads wondering why everything suddenly looks grainy.
- Very common: most Android devices (and other devices?) have a pixel ratio of greater than 1. This means that every "CSS pixel" actually gets displayed using more than one physical pixel - so a 200px by 200px image set to
width: 200px; height: 200px;will actually scale that 200px by 200px image up across more than 200 x 200 pixels, potentially making it grainy.
- Very common: many modern Apple devices have "retina displays". This is essentially the same as an Android device with a pixel ratio of 2, but with better marketing, and a few custom properties that allow it to be detected by name.
Any of these will result in John's problem of a gallery of images looking surprisingly grainy.
I was hoping someone would have a great solution to this problem, but for now here are my preferred options, starting with most effective but least universally possible:
- If possible, go vector - SVG (or Raphael.js if you still need to support IE8). Realistically, this is only an option for icons, diagrams etc, and it's never an option for photographs. Very complex SVG can also be clunky on low-end mobiles due to the processing required.
- If possible, detect the device's pixel ratio, and serve images based on that. This can also solve the Firefox on Windows problem because Firefox on Windows changes its reading of pixel ratios when it zooms in and out. The downside is, it becomes a tricky coding problem involving development work on the server and client side.
If 1. and 2. aren't possible, but it's really important and image quality is more important than, say, load time, just double up the image.
This is what Google do with their logo on their homepage: they squash a 538px x 190px PNG image in a 269px x 95px container. It's also more or less the same as how responsive images work.
This used to be considered bad practice because old versions of IE were terrible at scaling down images, but those are now very rarely used and much less common than high pixel density screens. It's still somewhat undesirable since it will increase image size and therefore increase load time - that's a trade-off you need to judge case-by-case.
- Doubling size is common because very few devices have a ratio greater than 2, very few users are zoomed in more than 200%, and scaling images 50% is cleaner than other amounts.
- If 1, 2 aren't possible and load times are too high a priority for 3, I'm not aware of any other options, and my recommendation is to not worry about it, because half the sites on the internet have the same problem, and people with this problem on your site will also have this problem on other sites. Hell, Firefox on Windows even pixelates its own UI buttons...