Forum Moderators: not2easy

Message Too Old, No Replies

Block Background Image Pixel Shift Across Browsers

Background image shifts by one pixel in different browsers.

         

ph0ed1n

3:22 pm on Jul 29, 2009 (gmt 0)

10+ Year Member



While the 'main div' within the 'body' is centered at 960px wide, "body {background: #000011 url(bg.jpg) center center repeat-y;}" puts a 1400px x 5px image with a 220px wide gradient fading into the background color equally on both sides of the 'main div'.

This setup does not work. If I edit the image in Photoshop to align the gradients in a way that lines up perfectly in IE8, FireFox 3.0.12 displays the image 1px shifted left, and Safari 4.0.2 displays it 1px shifted right.

As a fix, I created a 'wrapper div' between 'body' and 'main div' and moved the above background property to that, adding "width: 1400px;" and "margin: 0 auto;".

This works great (no more pixel shift), but...

Now there is a horizontal scroll-bar that appears when the window is shrunk to within 1400px (instead of properly at 960px), thanks to the new 'wrapper div' width being specified at 1400px (if I remove the width property, I get the same pixel shift problem again);

I tried "overflow: hidden;" in the 'wrapper div', but that did nothing.

I have seen what I'm trying to accomplish done elsewhere, though I refrain from providing an example for fear of violating the forum rules.

I've been able to avoid browser detection so far. Is this where I need to start implementing it?

Any prompt assistance is greatly appreciated, as I really need to get this to work soon.

swa66

12:59 am on Jul 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The trick is to make sure you use the same centering method on all your elements.

The reason behind it is rounding, and it's unavoidable for browsers to get it "wrong" if you do not use a consistent centering method.

e.g.:
Image auto margins:
your viewport is 800px wide, you center a 400px wide block in it:
we all would go (800-400)/2=200 so 200px on either side and no doubts.
Now imagine the viewport to have some scrollbars etc and be 777px wide.
(777-400)/2= 188.5 ... hmm. since browsers do render stuff on pixel borders ...
and cannot make the content a pixel shorter or larger,
they'll have to make one side a pixel larger than the other.
Which should they choose ?

Now imagine you have somewhere else absolute positioning used to center things:
left:50%;
margin-left: -200px;
the 50% of the width of the 777px wide viewport will have to be rounded too, 388 or 389 ?

Whichever the browser chooses, what if the code was using:
right:50%;
margin-right: -200px;
Ah now it would have to have calculated the 50% differently to position it in exactly the same spot.

IMHO the solution to this is to centersomethgin one and then use that position as the reference for all the rest, it's the only way to avoid these.

In addition to not requiring pixel perfect positioning (I recently hd a desgn needign it, and I had the positioning down in all browser, even the legacy IE6 adn IE7 browsers. It worked great till I zoomed in on the screen and the pixels didn't line up completely anymore as the zooming of a border and a image was slightly different (the image gets pixelated while the line is essentially vector info not needing that) ...

ph0ed1n

1:26 pm on Jul 30, 2009 (gmt 0)

10+ Year Member



While I now understand the rounding issue, sincere thanks to you, and appreciate your reference solution, I'm not sure how to implement that solution to resolve my problem.

The auto margin centered block ('main div') that matters most is the 960px wide one containing site content, etc., so that is what I want as a "reference for all the rest".

Just so I can walk through this to understand, let me first simplify things by removing my 'wrapper div' "fix", so the 'main div' is immediately the block within the body element.

The body element visually fills up the remaining part of the window (I assume the window is what you mean by viewport?) when sized somewhere greater than 960px wide.

I could specify a solid background color in the body element eliminating the rounding problem, but the centered 1400px wide background image visually frames the 960px 'main div' very nicely, so it is worth the effort to pursue its implementation.

I've seen the pixel-perfect-positioning solution implemented elsewhere, noting I'm happy to share this example to make it easier for you to see what I'm going for, if you don't mind an exception to your rule.

Apologizing if I'm being needy, noting I will be working by examining the aforementioned example's source code to see if I can figure out their method (not easy, they have a lot of code apparently), how exactly do I implement the 'main div' as a reference to avoid browser rounding?

ph0ed1n

1:50 pm on Jul 30, 2009 (gmt 0)

10+ Year Member



Upon further investigating the example site, they "suffer" from browser rounding too.

I hope you have a way to help me make this work, but if not, I will modify the image so the pixel shift isn't obvious (like the example site does).

swa66

1:26 am on Jul 31, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I typically use two ways to avoid the problems that come with pixel perfect positioning:

Position something somewhere and give it "position:relative" to make it's child elements that need position:absolute use the parent with position relative as a starting point.

Position all background on the html and then position the text containing element s over that making sure there is no need to have pixel perfect position by not giving thee text a background color and keepign away a bit from the edges.

I'm sure you cannot do all possible layouts that way, but it works in many cases.