Tutorials

Latest Word » Tutorials » Correcting the Center Aligned Background Bug
Correcting the Center Aligned Background Bug

Correcting the Center Aligned Background Bug

Tags:

This is an annoying bug that frequently pays us a visit when trying to align a combination of center aligned backgrounds. If you pay close attention, you will catch these bugs on a number of sites, but for those who don’t know what I’m talking about let’s take a look at the issue.

The Issue (Commonly seen in Firefox & Safari):

The bug appears when trying to align even numbered width backgrounds, with an odd numbered width browser viewport (or vice versa). For example, if the background is an even width of 970px, centering this in a browser viewport of 1501px can have buggy effects on where exactly to center align. This will result in causing this 1px unalignment bug.

Now you are probably thinking it’s not a big deal if the browser viewport is manually stretched to an odd number since most default browser sizes lands on an even width anyways. True in some cases, but in Firefox and Safari, once your content passes the fold and adds a vertical scroll, it creates a discrepancy within your perfect environment.

See Below for an Example (Firefox/Safari/Chrome)

1px background unalignment css bug

Since the vertical scroll throws in this discrepancy, I decided to take a closer look. It turns out the scroll is 17px wide (15px wide in Safari), which throws off our viewport/background total to an odd number.

1px background unalignment css bug

How do we tackle this issue?
We can try to hack this up targeting each browser, but it won’t solve this vertical scroll bug.

The Solution

To keep consistency with layouts with and without vertical scrolls, we can simply add the scroll by default and shift -1px on the unaligned background image.

html {
	margin-left: -1px;
	overflow-Y: scroll;
}

Unfortunately, Opera loses out when we implement this technique. To fix Opera, here is one nasty hack. *Note – Since this Opera hack cannot add properties to html and body tags, I had to force shift everything by -1px.

@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0)
{
	head~body *{ margin-left: -1px;}
}

Conclusion

Keep in mind this is not a complete fix. Once you manually adjust the viewport to an odd number, the mysterious 1px bug is back in action. The good thing about this technique is that it kills the bug for most standard browser/viewport sizes.

I mainly wanted to post this to see what other designers/developers have come up with to move around this bug. If you have come across this issue and have tackled it in a better way, I would love to hear about it!

Related Posts

Author Bio

My name is Soh Tanaka and I am a Los Angeles based designer/front-end developer specializing in CSS driven web design with an emphasis on usability and search engine optimization. I also run a CSS Gallery which is updated daily with the best CSS websites from around the world. Come check it out!

You can learn more about me or Twitter  Follow me on twitter for more updates and resources!

Did You Enjoy This Post?

subscribe  Subscribe via RSS or by email to get all upcoming tutorials and articles delivered straight to you.

+ Add Comment53 Peeps Have Spoken Their Minds...

  1. Kevin

    Good technique. I’ve been using it for some time.. keeps everything tight.

  2. Neal G

    I’ve also used border-left: 1px solid transparent; on a few sites I’ve done that had this bug. The real solution to the problem is to never make your main content DIV an odd numbered width like 771, 773, 775, 777 or 799.

  3. Soh

    Good point Neal.

    I think the main issue that gets me each time is when I use a 100% width X-p

  4. khamss

    Hi,
    I’m having the same problem, but not because of the scrollbar : the 1px bug appears or disappears when resizing the window. Actually it even occurs some times in your “Final Demo”!
    IE & Chrome don’t seem to be affected by this bug.
    I tried your fix in my layout; it seems to be slightly better, but the bug still occurs from time to time.
    Great blog, though!

  5. Moocow

    Wouldn’t it work just as well to put all content in a main div, center the main div and LEFT-ALIGN everything inside it, to force all divs inside it to lean to the left when the browser is an uneven width? Maybe, haven’t tried it yet.

  6. Jae

    Cool trick, it worked for me!

  7. TJ Mapes

    Brilliant! NICE.. thanks :) only took 5 seconds

  8. Ian

    This is the way to go! I was the having the same problem but only on my laptop resolution. When I viewed in 1600x… it was fine. It definitely has to do with Firefox’s interpretation of viewport.

    Thanks for the bugfix!

  9. Cristian Eslava

    Great, a mistery solved.

    It´s amazing how we have to deal with so many browsers and even with a 1 pixel to make a decent job.

  10. Carl

    The bug still appears… you did not solve the issue.

  11. Jeremy

    Worked like a charm. Thanks!

  12. James

    agggh, I remember wasting an embarassingly large amount of time last year after encountering this bug and trying to come up with a decent cross-browser solution.

    I got excited when I found that using fractions of a pixel for the problem div width seemed to work ok for FF whilst not affecting IE – eg {width:961.4px} (effectively forcing FF to perform some rounding calculation… but then you try resizing the window and it flickers around. Your solution has that problem too – but as you say it’s intended to work for most standard screen resolutions (at maximized size)… I suspect that’s the best we’re going to get… I’m certainly done tearing my hair out on that one and will design around it next time!

    James

  13. jw1487

    I’m having the same issue as ‘khamss’. It seems to be a problem with the window size, not the scroll bar. I understand, however, that the scroll bar does affect the screen size (of the website itself).

    This has got to be the lamest bug ever – Safari should make their scroll bar a freakin’ even-numbered width!

    But, my issue still really isn’t fixed. I tried your fix, and it fixes Safari, but breaks Firefox. The weird thing is, my site is not an odd numbered width … it’s even … 800px (I know it’s old school). And it’s only affecting the header (comprised of two background images on two div’s, both floated left). Anyway, I appreciate the fact that I’m not the only guy being frustrated by this. Thanks for the discussion, it has put me on the road to figuring this out.

  14. terje

    A very anoying bug indeed, however there is a permanent solution that works with any window size, you have to use a container element though.

    If you have a centered background with a width of 960px you write something like this:

    div#container { width:960px; margin:0 auto; background:url(/images/bg.gif) repeat-y 0 0; }

  15. Soh

    Hey Terje~

    That would indeed work but only for a background of the size of 960px. Most times people use a large background on the body so that the container width does not have to limit them with their backgrounds.

    I recently used a combination of backgrounds, one large about 1200px and another layer of 970px (to match the vertical repeat) and I bypassed this problem.

  16. Mike Walsh

    Yeah, like others have said, the scrollbar isn’t the issue. It’s practically impossible to get around if you need the background centered horizontally and repeated vertically the entire height of the browser. You can hack something with a table in quirks mode… but thats so ugly I refuse on principal.

    Javascript might be the answer…

    window.onload = function () {
    if (document.width % 2 == 1) {
    document.getElementsByTagName('html')[0].style.marginLeft -= 1;
    }
    };

    You’d need to add a way to recalculate on window resize… and I haven’t tested this in anything other than Firefox… I’m just thinking out loud.

  17. Soh

    Perhaps I was not clear with my description, I was stating that the scroll bar “does” add a curve ball to this situation (since the scroll itself is an odd numbered width).

    When it comes down to it, it all has to do with the odd/even browser viewport throwing the center alignment off, I was just stating that there is a difference in the viewport when the scroll bar is/is not in place~

    Thanks for the js method btw Mike!

  18. Maks

    I view this “view Final demo” link: http://www.sohtanaka.com/web-design/examples/1px-alignment-bug/ in browser:

    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.9) Gecko/2009042113 Ubuntu/8.04 (hardy) Firefox/3.0.9

    …and this final example is not aligned. I can’t say exactly how many pixels is the difference, maybe 1px or it could be 2px. Anyway I am on Ubuntu and found this page because many of my sites show in IE 6,7 and Firefox 2.X perfect, but in Firefox 3.X they show unaligned background images.
    Strange…

  19. Teddy

    Thank you so much for the tip – a simple, 5 second solution to a problem which I’ve never managed to wrap my head around. I have a div which I have to absolutely position on a page with a body background image, so the pixel placement of the div shows discrepancy across different browsers. Your fix immediately solved the problem (although I left out the overflow-y part since my pages are all taller than the browser height).

    However, it doesn’t seem to be a problem with the scrollbar. Instead, it’s the viewport size that is problematic, I think. Upon resizing the window, the bug appears after every 2 pixels moved (one odd-numbered and one even-numbered view-port width), but I couldn’t be bothered with that. Most people surf with the windows maximized :) and your fix works perfectly for maximized windows. Thanks again!

  20. tomexx

    This hack doesn’t work. I have tested it in FF3 and also in Google Chrome. Unalignment is still visible. :(

  21. Mehigh

    I’ve tackled this bug myself in a different manor.
    It seems that if you keep both your centered div width to be even, and also the background wide image you’re centering to have an even width, then they will both “shift” in the same time -> and getting a perfect alignment on even/odd browser widths with or without vertical scroll.

    You won’t have to bother with odd fixes for multiple browsers this way.

  22. DJ

    LOL Ok, I read this entire article and I think some people simply DONT READ. I dont want to speak for sohtanaka but come on and READ first.

    #1. It has everything to do with odd numbered pixels:
    “The bug appears when trying to align even numbered width backgrounds, with an odd numbered width browser viewport (or vice versa).”

    #2. This is not a perfect fix, it only fixes commonly used viewports (default viewports)
    “Keep in mind this is not a complete fix. Once you manually adjust the viewport to an odd number, the mysterious 1px bug is back in action. The good thing about this technique is that it kills the bug for most standard browser/viewport sizes.”

    #3. This is a fix for having a background on a div/body that is 100% which obviously will not always land on an even # pixel. So you cant just say “make them both even”

    Jeesh… and I just used this and it does everything promised in this article. I may try jQuery to shift the browswer viewport.

  23. Bernice So

    /* this seems to be work in IE. */
    /* has to be placed in an IE-only css */
    html {
    padding-left:1px;
    }

  24. Finees Mendez

    Hey,
    Thanks for the code. I’ve been looking for this for years now. Your awesome!

  25. Kavita

    hey,
    Thanks a ton for the code. It works well for me, I haven’t checked in all the browsers but works for the important ones. I spend my entire day trying to fix this problem and luckily I found your code and it worked in a second. Thanks again!

  26. Chris White

    Thanks for the Article, Mike’s JavaScript fix was only partially working, so I took the liberty of getting it fully working. If i hadn’t found this article, i would have just given up :)

    I tested this in FF 3.0.11 and IE 8.0.6 and they both work fine.
    However, I didn’t have any problems on IE 8 in the first place.

    Anyway, here is a full JavaScript fix.
    Include this js in your <head>:
    function alignment_bug() {
    if (document.width % 2 == 1) {
    document.getElementsByTagName(‘html’)[0].style.marginLeft = ‘-1px’;
    }
    };

    You will need this: <body onresize=’alignment_bug();’>

    And then add this inside your <body>:
    <script type=’text/javascript’>
    <!–
    window.onload = alignment_bug;
    //–>
    </script>

    I tried using window.resize in my js, but that failed.
    Enjoy!

  27. Chris White

    Your blog could do with converting < and > into &lt and &gt ;)
    Especially a coder related blog. Or can we use code, bbcodes?

  28. Chris White

    Actually, i realised afterwards that body onresize is not valid XHTML, and also, the margin will not change back for an odd width. So i made a perfect version, which utilises the window.onresize properly (Yes i did more research). Here is my full javascript patch.

    <script type=’text/javascript’>
    <!–
    window.onload = alignment_bug;
    window.onresize= alignment_bug;
    //–>
    </script>

    var alignment_bug = function() {
    obj = document.getElementsByTagName(‘html’)[0];
    if ((document.width + parseInt(obj.style.marginLeft)) % 2 == 1) {
    obj.style.marginLeft = ‘-1px’;
    } else {
    obj.style.marginLeft = ’0px’;
    }
    };

  29. David Conrad

    Man, so helpful – thanks, you saved me hours on this!

  30. Santana

    hey check this on Firefox, Safari And Google Chrome work fine but on 6 and Opera No =] check this pic..
    http://img266.imageshack.us/img266/1317/screenshotg.jpg

    ahh thanks for yours tut i lime your website =]

  31. Rob Schmitt

    I’ve converted Chris White’s fine JS snippet to jQuery (because I’m like that):

    $(function() {
    $(window).load(fixAligment).resize(fixAligment);
    });

    var fixAligment = function() {
    var obj = $(“html”);
    var doc_width = document.width + parseInt(obj.css(“margin-left”));
    var margin_left = (doc_width % 2 == 1) ? ‘-1px’ : ’0px’;
    obj.css(“margin-left”, margin_left);
    }

  32. schemogroby

    im using this css-bit to get rid of the alignment problem:

    body {
    margin-left: -.1px; /*1px shifting hack*/
    }

  33. Phil

    schemogroby’s solution works for me. But I have no idea why the point in front of the one fixes the alignment? (-.1px;)

  34. Rahul Chand

    I use margin: 0 auto !important; on any div that has a center aligned image

  35. Steen Nielsen

    Phil, the reason schemogroby put a point in there is because it makes it a decimal number.
    -.1px is the same as -0.1px.
    In CSS it is allowed to omit the number 0, when you use decimals.

  36. Hayo Maarsingh

    Thanks a lot Sohtanaka! One google search and I found your solution. Works in Opera too for me (version 9.64).

  37. Vali

    Hi, I have the same problem but the part that it’s not aligned it’s an Adsense flash ad. The misalignment can occur also on the vertical, when the firebug tab at the bottom it’s opened…

    The “solution” it’s not working.. the bug it’s still there, you just have to resize the window horizontally. But it’s good to know that others have the same problem and it’s not just my bad CSS skills :D

  38. Vali

    just upgraded to the latest ff: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2, and my problem disappeared without doing anything. Your hack it’s also working on the final demo. But the website without the hack it’s the same. So I guess they were two different problems, and the new ff solved mine but not yours….

  39. Hayo

    Helas, it’s not working in Opera 10…

  40. Rob Cubbon

    This sorted out a misalignment between the body background and the whole of the site. Only Safari remains one pixel out. Thanks for writing the post.

  41. Adrian N.

    I’ve been trying to find a solution to this shift for 2 days. I’ve tried so many different solutions and hacks and this is the ONE that finally worked. Please accept my grateful and heartfelt THANK YOU!

  42. Boudewijn

    Darn, none of the solutions posted worked for me. Chrome is the browser acting up. As soon as my content exceeds the 300px min-height that I have set, the background and navbar are thrown about a pixel to the right. Window resizing confirms that it’s related to the size of the display area.

    Nonetheless, thanks to everyone for sharing their tips. I’m back to troubleshooting.

  43. vinh khoa

    I encounter a similar bug on Chrome but the difficulty is I use % for my div widths (I dont like fixed width) so the numbers could be unpredictable, I suppose. However, increasing the percentage a little bit fixes the bug on most of the viewports I encounter. So thanks for the great post.

  44. Brandtley McMinn

    Hey all, I’ve never had this issue, and this post is the first I’ve ever heard of it. I suppose the reason why, and after reading a few posts back from early 2009, is that I use a centered, fixed-width div#wrap container to house ALL my page content and position everything relatively within it.

    This is a great practice for me, cuz I can move all the page content around the viewport at once, however Soh had responded to another persons post about this same technique, that backgrounds are only usable within the width of this wrapper div.

    This is not true, I only use the wrapper div for page content positioning. I use other “background” specific div’s outside of my #wrap div to achieve my background positioning. I’ve been using this technique since late 2008 and have never had such an issue as the one-pixel bug. Best part is that it’s a standards compliant solution :)

    Hope this helps someone.

  45. Krystal

    Brilliant. Worked like a charm.
    Well once I fixed my background images to be even widths that is. That was pretty key.

    For those who seem to be missing the point a little: the reason we are centering backgrounds is that we aren’t setting a width. The backgrounds are 1200px or 1080px or something larger than the lowest common denominator. We don’t want to set a width and set the margin to 0 auto because we don’t want horizontal scroll bars : )

    Another fix I have used in the past is if the content area is white and I am using a repeating background with a drop shadow or something I don’t include the content area white in the repeater and then set the color on the content div. Maybe I didn’t explain that really well but there is a post about it on my blog should anyone think it might work for them.

    Thanks for the fix Soh.

  46. Marlou

    Just what I needed. Thank you so much!

  47. bozghiyy

    Ohhh , you save me, i really lost a lot of time with this, and i did not understand what happens!

  48. Jay August

    You rule until eternity…. :) Thanks, this saved the day for me.

  49. Levanah

    Hi.. I have been having a problem for a long time with background alignments shifting one pixel back and forth when re-sizing the browser window (scrollbars or no scrollbars, just when i have divs with images that should align against a background image)
    I don’t know if this is what you are referring to cause when I view your Final Demo that same “wobble” is taking place where the header joins the background.

    Am I talking about something else or do you have a fix for this?

    Thanks!
    Miss A

  50. Robin

    Hi Guys,

    I’m not super professional CSS coder..but I got it fixed myself with a double DIV trick!

    Just don’t set background image through body tag. instead, use double div tag as below.

    body { margin: 0px; padding: 0px; } /* This is your body tag should looks like */

    #global_wrapper { margin:auto; width: 970px; } /* This is your main global fake wrapper, you can make it fixed width or even 100% what ever you want */

    #global_site_wrapper { width: 970px; margin: 0px; background-image: url(images/bg_shadow.jpg); background-repeat: repeat-y; background-position: center top; padding: 0px; float: left; } /* Here we have the trick and use your background here and again you can use 100% width or what ever you want */

    #content_wrapper { margin:auto; width:960px; } /* under here all your site contents goes and you can put all your header, footer, banners column all inside here */

    By this way I have achieved another massive problem fixed and that is you will see your background will have 100% height as well. Which means as long as your contents grows it will adjust the height of your browser automatically.

    So if you use double div tag trick you can always achieve 100% div height as well.

    Live site example >>>> http://training.visionarymotorsports.com/index_product.html

    Let me know if you guys didn’t have fix by following above technique

  51. Robin

    The above url changed..so try this one…

    http://training.visionarymotorsports.com/centhor_700.php

    I used the background shadow as center using double div tag.

  52. Luke

    I found only safari and chrome (recent versions) needed the fix. setting body background image x position to 50%, and then targetting safari and chrome with this:

    body:nth-of-type(1) { background-position-x: 49.99%; }

  53. Jerry

    Luke, you are greatest! It seems that most browsers have fixed the issue and I’m only encountering it in Safari and Chrome. Your hack totally fixes the issue. I’ve added the following to my css file and I have a pixel-perfect background centered in the body with a repeat-y:

    @media screen and (-webkit-min-device-pixel-ratio:0) {
    body:nth-of-type(1) { background-position-x: 49.99%; }
    }

Speak Your Mind...

Post HTMLNeed to Post HTML Code? Use Postable to post code friendly html. *Wrap all html code in <pre></pre> tags.
Post HTMLNeed to Keep Updated with Comments? Subscribe to comments now.

CSS Gallery