24

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 ?

Cheers

5
  • 2
    Great question, this is something that bugs me often. This article is useful background reading, but I've not yet seen any perfect answer to this, beyond putting in x2 size images with fixed widths and heights and letting the browser sort it out (has obvious downsides, but fixes this and pixel density issues). Sep 8, 2014 at 10:35
  • I'm not sure what kind of answer do you expect. Obviously, you don't want to use auto resizing. Are you asking how to stop the browser from resizing the images so the other elements will be arranged around the original image size? How to automatically deliver prepared images for each possible zoom level? Or what do you have in mind? Besides, why do you want to do this? If a user has difficulty seeing the page properly at the original zoom, they probably won't notice the difference between sharp and auto-resized after zoom.
    – Rumi P.
    Sep 8, 2014 at 10:36
  • 8
    You don't handle it. This is a user preference. No need to interfere with it.
    – DA01
    Sep 8, 2014 at 15:52
  • 1
    He's not asking how to interfere with the user's preferences. He's asking how to handle the fact that a lot of users are zoomed by default, and will therefore get grainy images if the images are at their original dimensions. Sep 8, 2014 at 16:38
  • @user568458 yep. That's how it works. There's really nothing to handle.
    – DA01
    Sep 8, 2014 at 22:15

9 Answers 9

22

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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...
4
  • I contest that users zooming in is 'most rare'. That's pretty much why the feature is there in the first place...to zoom in. Also, while there are interesting ideas with using higher resolution images upon zoom, note that there could be usability challenges with that. For instance, I don't want the browser to go fetch new images every time I hit the zoom option in my browser.
    – DA01
    Sep 8, 2014 at 22:18
  • 2
    If you're using jpgs, doubling the size of images (as mentioned in 3) and saving them with a fair bit of image compression (as low as quality 40) can give you small file sizes. Once scaled down the compression artefacts aren't visible. Results vary, especially where images contain gradients.
    – Dominic
    Sep 9, 2014 at 2:30
  • 1
    Although very new at the time of writing and thus ill supported, the new <picture> element seems to warrant mention here.
    – user50849
    Sep 9, 2014 at 5:29
  • 1
    Of note: When saving for web in photoshop, setting the jpg-quality to 61% while having double the intended dimensions, the file size will be almost exactly the same as intended dimensions at 100%. So I've started compressing all my jpegs to 61% and serving them with a defined height/width (which also has the advantage of letting the browser know more about layout even before the image is loaded!) Sep 9, 2014 at 7:02
4

As DA01 commented you should not do anything about it.

Zoom is a user-specified option and therefore is under their control. The settings they decide to mess with shouldn't be your responsibility.

You can account for different browsers and versions and what not, but reasonably speaking you shouldn't account for a user's zoom.

Sure you may account for 125% or 150% (and you may not even have to). But 200%, 300%, more? It just doesn't make any sense.

What if the user uses the high contrast windows theme? What if they are constantly using the magnifier? Who cares?

Ideally your website is flexible enough that it doesn't make a real different between small zoom difference, but images will decrease in quality with zoom but that isn't your responsibility.

This is of course just my opinion but the company I work for also explicitly tells customers that we do not support their zoom preferences.

1
  • whatabout users with ultrawide or narrow gamut devices etc etc.... yes i agree
    – joojaa
    Sep 8, 2014 at 17:45
1

Other people have given some great tips on the problems that you'll face and I'm not good enough in this area to do a good tutorial but...

You may want to design a responsive site that adjusts according to the user's res/device and then you're probably looking for code that will switch images to higher or lower res files when requested, rather than stretching and squeezing the images you have.

When I last tried to do this, I used media-query.js and picturefill.js. See: http://responsivedesign.is/resources/images/picture-fill . I had a 3 column layout where some images would span two columns... When the browser window was made small enough, the large images would switch to a smaller res version that would only be one column wide. The user's browser would just load the version of the file that they needed. (and in my case, masonry plugin would move everything to accommodate).

Of course then your user has to have javascript enabled...

1
  • While I'm all for responsive web design, that handles a different problem (reflowing to handle different browser sizes) than user-zoom (which is proportional resizing of everything independent of the browser size)
    – DA01
    Sep 8, 2014 at 22:19
0

You can not force the users hand. The user settings are not yours to play with. Settings and circumventing them is a bad idea there might be a reason why the user did something. In either case you can not guarantee anything across the various devices.

In fact if you go into the technical side it becomes even more interesting. You really give the keys to the kingdom with your webpage. See the user downloads the webpage and the user can now do whatever they like with it. You have no control over this layer, it is after all running on the users machine and they can do whatever they please. Even stackexhange does not look the same on my computer/mobile as it does on yours. I change some aspects of the GUI in my end automatically, to fix 2 rendering bugs and have added 2 shortcuts.

7
  • 3
    I think they're not trying to prevent the user zooming in, but make sure that if, for example, the user's browser defaults to 125% zoom because Windows is strange, the images still appear crisp and don't appear pixelated. Sep 8, 2014 at 11:02
  • 1
    Does not matter, same thing
    – joojaa
    Sep 8, 2014 at 14:05
  • 2
    They're really not the same thing... for example, Google's logo is a 538px x 190px PNG image in a 269px x 95px container. This means, if you were zoomed in, or using a high pixel density screen, the image is less likely to be pixelated because the browser can use that extra pixel data. Google are not playing with the user's zoom settings by doing this. Sep 8, 2014 at 14:19
  • What you do in your end is up to you yes. But if somebody uses a 259% zoom then..
    – joojaa
    Sep 8, 2014 at 14:25
  • 1
    well your thinking of today, things will change in the future, very close future. So anybody with vision problems might have 200% today tomorrow 200% will be the norm compensating just makes the problem worse. In either case the problem will grow out of hand sooner or later. You just can not do more than temporary victories, the system must change.
    – joojaa
    Sep 8, 2014 at 17:39
0

The annoying behaviour of upscaling images on HiDPI screens, which leads to blurry photos (aka the photographers nightmare), has also troubled me for quite some time. I also wondered that there is no simple CSS attribute to disable that for images.

My current solution with CSS looks like this:

@media only screen and (min--moz-device-pixel-ratio: 1.25),
    (-o-min-device-pixel-ratio: 5/4),
    (-webkit-min-device-pixel-ratio: 1.25),
    (min-device-pixel-ratio: 1.25) {
        img {
            --pic-width: 460px;
            width: calc(var(--pic-width) / 1.25 - var(--pic-width) + var(--pic-width));
        }
}
@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {
        img {
            --pic-width: 460px;
            width: calc(var(--pic-width) / 1.5 - var(--pic-width) + var(--pic-width));
        }
}
@media only screen and (min--moz-device-pixel-ratio: 1.75),
    (-o-min-device-pixel-ratio: 7/4),
    (-webkit-min-device-pixel-ratio: 1.75),
    (min-device-pixel-ratio: 1.75) {
        img {
            --pic-width: 460px;
            width: calc(var(--pic-width) / 1.75 - var(--pic-width) + var(--pic-width));
        }
}
@media only screen and (min--moz-device-pixel-ratio: 2.00),
    (-o-min-device-pixel-ratio: 2),
    (-webkit-min-device-pixel-ratio: 2.00),
    (min-device-pixel-ratio: 2.00) {
        img {
            --pic-width: 460px;
            width: calc(var(--pic-width) / 2.00 - var(--pic-width) + var(--pic-width));
        }
}

Next step would be using classes to define and set different image sizes if needed. I don't know a way to dynamically get the image sizes. The CSS Function attr() seems not to work for this.

0

Another possibility is the following. The only problem is that the image still uses 100% of the space. This means that there will be empty space around the image after it is resized.

@media only screen and (min--moz-device-pixel-ratio: 1.25),
    (-o-min-device-pixel-ratio: 5/4),
    (-webkit-min-device-pixel-ratio: 1.25),
    (min-device-pixel-ratio: 1.25) {
        img {
            transform: scale(0.8);
        }
}
@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {
        img {
            transform: scale(0.6666666666666667);
        }
}
@media only screen and (min--moz-device-pixel-ratio: 1.75),
    (-o-min-device-pixel-ratio: 7/4),
    (-webkit-min-device-pixel-ratio: 1.75),
    (min-device-pixel-ratio: 1.75) {
        img {
            transform: scale(0.5714285714285714);
        }
}
@media only screen and (min--moz-device-pixel-ratio: 2.00),
    (-o-min-device-pixel-ratio: 2),
    (-webkit-min-device-pixel-ratio: 2.00),
    (min-device-pixel-ratio: 2.00) {
        img {
            transform: scale(0.5);
        }
}

CSS method 'zoom' works as expected (instead of scale), but its non-standard and does not work with Firefox.

-1

So this would be more of a programming question. But using JQuery, or even just plane css you can display different images based on the users screen width, screen height and so on.

Again though this probably isn't the stackexchange to ask.

1
  • The question isn't about screen size. It's about browser zoom settings.
    – DA01
    Sep 8, 2014 at 22:21
-1

You can simply do this via HTML in the head of the site add this

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

This isn't recommended by developers for every type of site but should accomplish what you're asking.

2
  • I don't think this has any effect on a desktop browser.
    – DA01
    Sep 8, 2014 at 15:53
  • 1
    I've tried this to address the same problem recently and it doesn't work. Also, even if it did work, it'd be solving the problem the wrong way - preventing zoom, instead of making images maintain clarity when zoomed. Sep 8, 2014 at 16:36
-1

Hope it helps: css rule transform: scale on body tag or another - not perfect see here, please:

https://stackoverflow.com/questions/23099849/stop-firefox-dpi-scaling-when-windows-setting-is-at-125/42755741#42755741

1
  • Welcome to Graphic Design! Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
    – Luciano
    Mar 13, 2017 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.