Once again, one of my clients sprung a uniquely difficult web development issue on me. This one took me quite by surprise, and it might upset you to find out that even after spending between 3 and 5 days working solely on this, I only came up with a partial solution. If you have this problem, I describe a partial fix at the end of the article which might help you, especially if you have good JavaScript programming skills.
The problem is best described as – Internet Explorer displaying Jagged / pixelated images on high-dpi screens.
You’ll know if you have this problem if on one computer the Google logo looks like this:

And on another it looks normal, like this:

If your computer only shows the normal version, well great, you’re currently in the majority of Internet users, but I personally believe we are going to see this issue crop up more and more because of the causes.
I guess it’s best if I explain this problem (and how to reproduce it on your PC), so that you can understand how, and why, this is happening.
Historically most Windows PCs have been shipped with display resolutions of 96dpi.
This doesn’t mean that all your web images need to be at 96 dpi, it means that your screen displays images at 96dpi – which is different (why?)
However recently, many computer screen manufacturers are managing to squeeze more and more pixels onto your screen, which is leading us towards ultra high resolution screens.
All cool so far, we get much better screen sharpness etc, sounds great! But unfortunately having so many pixels on the screen means that things which were once a decent size (e.g. text) are now much smaller because ultimately the pixels they are displayed on are smaller.
Imagine you have a font set to 11 pixels height – pretty standard for many work processing applications, now imagine those same 11 pixels occupy 0.8% of the screen space they used to. Now our 11 pixels high text looks more like 9 pixels text which, as you probably know, is much harder to read.
So what’s the solution? Well a higher DPI increases the size of the fonts on screen. (how?)
So this is what many PC manufacturers are choosing to do – increase the dpi that they ship your Windows PC with.
In fact this in itself is fine; it still doesn’t cause a problem for us web developers.
However, helpful Microsoft, decided to integrate a system into Internet Explorer that will automatically scale images up relative to the DPI that the screen is set to. That sentence doesn’t really justify the problem well enough but look again at those Google logos above. Imagine your beautiful website, with nice 72dpi images, compressed to save space, was suddenly scaled up and not even scaled using a decent scaling algorithm. Scaled so it just pixelated, not good!
Now fortunately MS don’t ship Windows with this setting enabled by default (sincerely thank you MS, you’ve saved us web developers a LOT of misery!)
But, in their infinite wisdom, DELL and possibly Toshiba did (at least at one point) decide to ship their PCs (the ones with Ultra High Res screens, UXGA) with this setting enabled for Internet Explorer.
Guess what PC my client had!
So, after many hours searching on Google what did I find – well, not a lot to be honest, or at least not much of use to me.
I’d just finished a very graphic intensive website, that look amazing in all my many web browsers only to have my client asking why it looked so rubbish and why it was so pixelated.
So let’s start with reproducing it – for those of you who are interested.
Right click on your desktop and select ‘properties’
Go to the settings tab and click ‘advanced’

Then using the dropdown menu change your DPI from 96 – 120 DPI.

Click ok
Your PC might ask you to restart at this stage – don’t
Next thing to do is open regedit (only use this if you’re confident using it – I am not responsible if you mess up your PC.)
Now we want to go to the following registry key:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
And we want to change the value of from:
“UseHR”=dword:00000000
To:
“UseHR”=dword:00000001
Now restart your PC. By the time you’re back up and running you’ll notice all your icons and fonts are much bigger. Now look at your favourite websites and you’ll see the nice pixelated effect of the first Google image above.
Ok, well if you actually did that you might want to set everything back to how it was now.
Anyway, now you’ve seen how to enable this, you might want to try Firefox or another web browser – notice how they’ve not pixelated your nice images.
So what’s the beef? Well, I guess MS wanted to improve the accessibility of websites on high DPI screens which is great, and DELL just wanted to make use of that, but clearly DELL didn’t think this one through, you can’t just switch these things on and hope for the best
So what can you do? Well the truth is – your options are limited. Here are the various options that you can try:
- Tell everyone to turn off this setting or switch back to 96DPI. Not exactly practical to ask everyone to edit their registry just to visit your website now is it? And how do you tell your client they are in the vast minority – it’s not easy let me tell you!
- Somehow automatically turn this setting off. Well it’s a nice idea but if you managed it, technically you would be hacking, because the only way to do this is to modify the users’ registry, and if you found a way to automate this from a website – well you’ve got to be bloody good at programming and not afraid of a lawsuit.
- Redo all your images at a higher DPI to prevent the pixilation. This would work, but come on, we’re talking about a minority of users and it’s an awful lot of work for some sites! Mine fell into that category.
- Have two folders of images, detect the browser and the screen res and serve up the lower DPI images to those people who use an unaffected web browser and/or don’t have their screens at 120 DPI. Then if you get someone using IE7 at 120DPI serve them the other image folder with high-dpi images. This is technically probably better than idea 3 but wow what a lot of work.
- Use Scalable Vector Graphics, well this would be amazing, but not all web browsers support SVG so you could alienate lots of your users.
Those are the main solutions I found / dreamed up, but there is one more possibility – and I hope this helps you!
- Use JavaScript to detect the current screen resolution and if the screen is scaled up, automatically rescale the images back down to their intended size.
There it is! that is my partial solution. I say partial because I discovered a limitation to JavaScript that I (personally) couldn’t get around. I couldn’t scale background image back to their normal size.
So unfortunately my tale ends with some slight sorrow. I had to tell my client that she was in the minority of users and that most people visiting her site would not see the problems she was seeing. Which is a shame since I nearly cracked it.
Anyway for those of you who are looking for a solution, perhaps this will help you:
//This function finds the scaling factor that the browser has implemented
function fnScaleFactorX()
{
nScaleFactor = screen.deviceXDPI / screen.logicalXDPI;
return nScaleFactor;
}
//This function, which doesn't work is meant to re-scale the entire site back down to it's intended size.
function fnScaleManually()
{
// normal DPI
var constNorm = 96;
//scaling is off and DPI higher than normal
if ((screen.deviceXDPI != screen.logicalXDPI) && (screen.deviceXDPI > constNorm))
{
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var value = constNorm / screen.deviceXDPI;
document.body.style.zoom = value;
}
}
//This function which kind of works is meant to re-scale every element back to it's intended size.
function ScaleSize()
{
if (screen.deviceXDPI != screen.logicalXDPI)
{
//Scale images
var objects = document.getElementsByTagName("img");
for(var no=0; no<objects.length; no++)
{
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.width = newW;
objects[no].style.height = newH;
}
//Scale divs
var objects = document.getElementsByTagName("div");
for(var no=0; no<objects.length; no++)
{
//Normal Div Widths
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.width = newW;
objects[no].style.height = newH;
}
//Scale divs
var objects = document.getElementsByTagName("div");
for(var no=0; no<objects.length; no++)
{
//Normal Div Widths
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.backgroundImage.Width = newW;
objects[no].style.backgroundImage.Height = newH;
//alert(objects[no].id);
}
//Scale paragraphs
var objects = document.getElementsByTagName("p");
for(var no=0; no<objects.length; no++)
{
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.width = newW;
objects[no].style.height = newH;
}
//Scale input fields
var objects = document.getElementsByTagName("input");
for(var no=0; no<objects.length; no++)
{
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.width = newW;
objects[no].style.height = newH;
}
//Scale selects
var objects = document.getElementsByTagName("select");
for(var no=0; no<objects.length; no++)
{
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.width = newW;
objects[no].style.height = newH;
}
//Scale forms
var objects = document.getElementsByTagName("form");
for(var no=0; no<objects.length; no++)
{
var imgH = objects[no].clientHeight;
var imgW = objects[no].clientWidth;
var scale = fnScaleFactorX();
var rescaleVal = 1 / scale;
var newH = imgH * rescaleVal;
var newW = imgW * rescaleVal;
objects[no].style.width = newW;
objects[no].style.height = newH;
}
}
}
Here are some useful links:
This is where I borrowed the Google screen grabs from:
UXGA screens
http://en.wikipedia.org/wiki/Display_resolution
More info:
http://webkit.org/blog/55/high-dpi-web-sites/
http://www.henrykautz.org/Computers/high_resolution_laptops_and_inte.htm
One Trackback
[...] dpi versus 120 dpi setting some people’s (my boss’s) computers have. i was lucky a more knowledgeable cat had attempted to solve this problem before. where this [...]