16
Feb

Fixing One Pixel in Safari

Posted 3 years ago, mid-February.

Prednisone Online Buy Lotrisone Lipitor Online Buy Lipitor Erythromycin Online Buy Coumadin Penisole Online Buy Phentrimine Zelnorm Online Buy Elavil

Safari BugI’ve been frustrated by a 1 pixel background-image shift in Safari ever since I discovered the bug last May. The problem occurs when positioning background images using the ‘center’ keyword. It’s a rounding problem - odd window widths cause centered background images to misalign with centered div’s. I spent hours tweaking style sheets, but met no success. After months of discontent I finally sat down and wrote a quick javascript fix for the problem.

Update: I discovered a very simple general solution, though it presents new problems.
Update 2: I’ve found a simple solution that works for all rounding cases with no apparent bugs.

The Problem

Below are some screenshots of the home page before applying the fix:
1 Pixel Shift
1 Pixel Shift
My fix hasn’t yet been applied to subpages, so the problem is still visible at the bottom of this page as well.

Obviously a one pixel shift isn’t a design-breaking bug. In fact, only one other person has actually noticed it. But it’s certainly an annoyance and worth fixing.

Heres the bits of CSS that cause the problem:

#main {
    background: url(images/mid.gif) top center repeat-y;
    ...
}
#footer {
    width: 100%;
    text-align: center;
    margin: auto;
    ....
}
#footcontent {
    background: url(images/footer.gif) top center no-repeat;
    width: 980px;
    margin: auto;
    ...
}

UPDATE: General Solution

This code works in all cases, but it forces a browser resize when an odd browser width is detected. In other words, the browser is forced into an even width where the rounding error doesn’t occur. Unfortunately the fix itself produces another bug: the window will sometimes momentarily flash to white when resizing. Update: By adding a simple delay, the flash-to-white problem has been solved.

window.onload = resizeIfOdd;
window.onresize = forceSafariEven;

function resizeIfOdd(){
if(navigator.userAgent.indexOf('Safari') != -1)
 if(document.documentElement.clientWidth % 2 == 1)
  window.resizeBy(-1,0);
};

function forceSafariEven(){
 window.setTimeout('resizeIfOdd()',5);
};

Shortcomings

  • Screen occasionally flashes white when resizing browser window.

Download the Script

Download .zip file Download (.zip) - 0.6 KB

Thanks to Mike Vierow for sending me his research on this subject.

If anybody has any suggestions for how to improve my code, please leave them in the comments below or drop me a line.

Technorati Tags: , , ,

Posted under Design, Software.
  1. Ted Jacobson   gravatar

    I’ve come across this exact same problem once before. Forcing the window to an even width is an interesting solution, although a better solution might be to resize some container element within the document to an even width rather than the window itself. I don’t know if that’s even possible to do - body or html would have to be resized by -1px. I wound up just leaving the bug, but this script seems like an easy fix. Thanks.

  2. D. S.   gravatar

    I see I am not the only person that has experienced this issue. However, this solution is not complete. On browser window resize when the window is smaller than the page, this script produces some strange results. For example, it locks the height of the browser window.


  3. D.S., what version of Safari are you using? I created and tested it on Safari 2.0.4, so it may produce strange results with other versions that I’d be happy to address.


  4. Hey, thanks a million for this solution!

    However, the bug appears in more browsers than just Safari. In fact, the bug appears in all browsers built upon WebKit…

    Solution:
    Change “if(navigator.userAgent.indexOf(’Safari’) != -1)â€? into “if(navigator.userAgent.indexOf(’WebKit’) != -1)â€?


  5. I’ve developed a method that overrides the positioning of the background and does it by hand. More elaborate, but doesn’t resize the browser.

    http://zomgforeelz.blogspot.com/2007/05/centering-in-safari-and-ie-off-by-one.html


  6. I just finished writing my code when I stumbled across your post. This is my version.

    if (/(?:AppleWebKit|KHTML)/.test(navigator.userAgent)) {
    window.force2pxWidths = function()
    {
    if (window.innerWidth & 1) window.resizeBy(1, 0);
    }

    window.onload = window.onresize = function()
    {
    window.setTimeout(force2pxWidths, 1);
    }
    }

  7. Dell   gravatar

    Thanks for this great hack. I’ve been searching awhile for something like this and it seems this does the trick. Thanks much.

Leave a Reply