Correcting the Center Aligned Background Bug
Tags: Beginner
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)

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.

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
Follow me on twitter for more updates and resources!
Did You Enjoy This Post?
Subscribe via RSS or by email to get all upcoming tutorials and articles delivered straight to you.




+ Add Comment53 Peeps Have Spoken Their Minds...
Good technique. I’ve been using it for some time.. keeps everything tight.
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.
Good point Neal.
I think the main issue that gets me each time is when I use a 100% width X-p
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!
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.
Cool trick, it worked for me!
Brilliant! NICE.. thanks :) only took 5 seconds
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!
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.
The bug still appears… you did not solve the issue.
Worked like a charm. Thanks!
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
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.
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; }
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.
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.
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!
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…
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!
This hack doesn’t work. I have tested it in FF3 and also in Google Chrome. Unalignment is still visible. :(
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.
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.
/* this seems to be work in IE. */
/* has to be placed in an IE-only css */
html {
padding-left:1px;
}
Hey,
Thanks for the code. I’ve been looking for this for years now. Your awesome!
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!
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!
Your blog could do with converting < and > into < and > ;)
Especially a coder related blog. Or can we use code, bbcodes?
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’;
}
};
Man, so helpful – thanks, you saved me hours on this!
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 =]
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);
}
im using this css-bit to get rid of the alignment problem:
body {
margin-left: -.1px; /*1px shifting hack*/
}
schemogroby’s solution works for me. But I have no idea why the point in front of the one fixes the alignment? (-.1px;)
I use margin: 0 auto !important; on any div that has a center aligned image
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.
Thanks a lot Sohtanaka! One google search and I found your solution. Works in Opera too for me (version 9.64).
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
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….
Helas, it’s not working in Opera 10…
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.
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!
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.
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.
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.
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.
Just what I needed. Thank you so much!
Ohhh , you save me, i really lost a lot of time with this, and i did not understand what happens!
You rule until eternity…. :) Thanks, this saved the day for me.
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
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
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.
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%; }
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...