Fixing Safari’s 1px background-image centering bug

I’m working on slicing and CSS for a new theming project for Magento Commerce and was plagued with a CSS bug that affects WebKit (Safari and Google Chrome).  After some searching I found that several other people have had the problem, but I didn’t see a comprehensive writeup of the solution.  Here’s what I found…

Bug description: When having a centered background image over a centered div (like a drop shadow over a main content div), the background image’s position would sometimes be “off” by 1px as the viewport in Safari, depending on the width of the viewport.  So half of possible viewport widths would show the incorrect version.  While 1px isn’t the end of the world, it can really hurt a design, and it’s nice to get center alignment in Safari/Chrome to work like Firefox/IE.

Example code:

body {
    background: #f8f8f8 url(../images/dh_bg.jpg) 50% 0 repeat-y;
}
div#everything {
    width: 980px;
    margin: 0 auto;
}

Partial Solution: First of all, always use an even-width background image – this way the rest of the browsers will get it right automatically.

To fix Safari we can apply a CSS hack targeted towards WebKit.  If your background image’s width is just a little wider than your main div, then this will fix it:

@media screen and (-webkit-min-device-pixel-ratio:0) {
    body {
        background-position: 49.999% 0;
    }
}

The problem with this is that if the viewport is resized to be a little larger than your div, but not as large as your background image, then the 1px problem comes back.

Real Solution:
So my solution is always use an even-width background image that is wider than the devices you want to support. I made mine 5000px wide (which is still < 1kb).  Then, the following CSS works great:

@media screen and (-webkit-min-device-pixel-ratio:0) {
    body {
        background-position: 50.001% 0;
    }
}

Hope that helps somebody.

Thanks to the helpful comments on Rob Goodlatte’s post (a JavaScript solution), which helped point me in the right direction.

Follow @philfreo on Twitter

Want to know when I write another post? (very infrequent)

17 Comments

  1. Woodspiral said,

    May 7, 2010 @ 8:49 am

    Yes, this indeed helped me at least. I always seem to bump into this problem sooner or later when designing a layout. Thanks for the post and simple solution!

  2. Mark Hutton said,

    June 16, 2010 @ 9:09 am

    Thank you, this worked great for the very latest versions of Chrome and Safari.. it was a major bummer when I first noticed the issue & then messing around with negative margins etc to no avail – now it looks fine

  3. colin said,

    August 1, 2010 @ 3:04 pm

    Oh thank you! You solved my centering problem that was bugging me for the past couple hours.

  4. Pacoup said,

    December 10, 2010 @ 12:39 am

    Works great. However, it breaks Opera’s correct centering, which means Opera must be doing something else than Mozilla and IE which don’t get affected by this bug.

    Tested in and works in: IE7, IE8, IE9, Chrome 8, Safari 5, Firefox 3.6, Firefox 4

    I guess that if your design must really work with this background trick, it’s a choice between leaving behind 18% of your users (Webkit -> Safari/Chrome/iOS/Android) or less than 2% (Opera).

    lol
    Thanks for the tip

  5. Phil Freo said,

    December 10, 2010 @ 1:00 am

    @Pacoup: Sorry, but this doesn’t make sense. If Opera does “correct centering” (like Firefox) then it will work fine. The “fix” here is special webkit only code that will be completely ignored by Opera since it’s not a webkit browser.

  6. mark said,

    November 4, 2011 @ 3:20 pm

    Thanks, man. This was driving me crazy and your fix solved it.

  7. Davor Tomic said,

    December 16, 2011 @ 9:37 am

    Thank you very much Phil, your fix saved me a lot of headache! Worked like a charm :)

  8. Mos said,

    December 24, 2011 @ 2:21 pm

    It’s almost 2012 and we still have this bug.

  9. Jeaffrey Gilbert said,

    January 12, 2012 @ 4:44 am

    I didn’t work for me before I update my background image size to 5000px. Now it works, thanks.

  10. Jeremy Carlson said,

    January 17, 2012 @ 2:13 pm

    Perhaps @Pacoup was trying out `background-position: 50.001% 0;` without the media query. I was tempted, too, and may investigate further.

    In any case, this worked elegantly for me with a minimum of fuss. Thank you!!

  11. Tobias said,

    January 18, 2012 @ 5:23 am

    Thank you, You have saved my first working day :)

  12. Renato said,

    February 20, 2012 @ 4:27 pm

    Thank you very much.
    It worked perfectly xD

    (in my case, worked with 49.99)

  13. Paul said,

    November 16, 2012 @ 10:37 am

    Three years on from Phil’s workaround and this bug STILL exists in Chrome etc. What is wrong with the developers? Do they live in a sealed box? I guess so…

    Many thanks for the fix, going to try it now.

  14. Paul said,

    November 16, 2012 @ 11:22 am

    OK, tried it now. Fantastic, it worked, many thanks!

    It worked for me with 5000px background image and 49.999% rather than 50.001%. As long as it works I am happy, and my client will stop asking why ‘that bit is shifted over and looks all wrong’.

  15. pk said,

    December 5, 2012 @ 6:41 pm

    This seems to be fixed in Chrome now, but still plagues Safari (at least for me). Thanks much for writing on this, it was driving me nuts.

  16. Chankey Pathak said,

    May 13, 2014 @ 1:39 am

    Link to Rob Goodlatte’s post is dead. Can you post a snippet of JS code?

  17. Phil Freo said,

    May 17, 2014 @ 1:38 pm

    I don’t have his code — but I remember after looking at it that I realized a CSS only solution was possible (and wrote this post)

RSS feed for comments on this post