September 23, 2005

CSS IE one pixel image offset hack

CSS IE image background one pixel offset

For some time, I've been trying to center the Designer Jones website. The road was long and fraught with peril … <grin>

Designer Jones was designed to look like a magazine. Its construction means it's not the sort of design that is easily centered — because the "top" of the design is a one-piece header image (the gray downcurve next to "Main Menu" is the bottom edge of the image) and I wanted the text in the two right columns to start at the top of the "page". To effect this, I used CSS-P (absolutely positioned divs, or "layers" to you Dreamweaver folk) to hold that text in place on top of the image. The positioning nailed it there, beautifully unmoving, seemingly unbreakable. It also meant that DesignerJones was stuck to the left side of the screen in larger monitors. Besides, even if I ultimately decided that left-side was what I wanted, I wanted to have a choice about the matter.

I recoded and tested in Opera 8, Mozilla, Firefox and IE 5.5 and 6. After numerous trials, most of which made it work in most browers but not all, I finally hit upon a solution.

Note that I cut the top image into two; the gray logo on the left and the two "pages" image to serve as background on the right. The code:

body {background-image:#fff url(whatever.gif) center repeat-y;)

<div id="maincontainer" fixed width, margin:auto>
  <div id="contentcontainer" floats left>
    <div id="thelogo"><img src=LOGO HERE></div>
    <div id="thecontent"> </div>
  </div>

  <div id="sidebarcontainer" floats right
  RIGHT-SIDE IMAGE AS BACKGROUND HERE>
    <div id="leftnav" floats left> </div>
    <div id="rightnav" floats left> </div>
  </div>
</div>

The IE one-pixel image shift

The problem was that, in IE 6, the header image was shifted to the left by one pixel, making the design look … well, stupid. If you're going to have lines, vertical or otherwise, they should align.

I tried, of course, the various IE hacks for feeding one margin to IE and another to the rest of the browsers. That worked for IE6 but I encountered what, to me, was always going to be the nightmare scenario: a hack that works in one version of IE but not another. While my solution worked gloriously in IE6, it misaligned in the same way in IE5.5.

Then, finally, a clue: that IE may be centering based on screen width less scrollbar. That
is, perhaps the problem was not that the two top images were shifting, but that the background image in the body tag wasn't quite centered?

A quick hack, and all was well:

body {margin:0; padding:0; font-family:etc;
background: #fff url('bk.jpg') center repeat-y;
margin-left:1px} <= for IE

html>body {margin:0} <= for other browsers

I'm sorry that I've since cleared my history and cache; I'd like to credit the person who posted the clue. In any case: may good befall you.

ADDED 10/29/09: If you do not have to split up the header image, then it's best to ensure that the header image is an even number of pixels … that is, 900px rather than 931px. This tip may save you from unnecessary craziness.

23 Comments to "CSS IE one pixel image offset hack"

  1. Graham Birks says:

    Lady, you just saved me lots of hair pulling out. I take my hat off to you.

  2. DianeV says:

    You are most welcome. We all help each other out here on the Web; without that, things would go a lot slower. <grin>

    I ended up doing DesignerJones a different way entirely: by putting the "book background" (the part that extends downward on the page) into an outer div that encloses everything:

    <div style="background:url(image) repeat-y)>
    <div style="float:left">content here</div>
    <div style="float:right">menu here</div>
    </div>

    The problem with that, though, was that some browsers would not display the div's background image. (How lame is that?) (Etc.) All that was left of the visuals was the two header pieces at the top … no further background under the page content, navigation, etc.

    I was finally able to determine that the problem only occurred when the outer div contained floats. By tinkering with it, I found that it was easily solved by adding something *after* the two floats (but before closing the outer div):

    <div style="clear:both"> </div>

    And -presto- the page background appeared. I'm no Eric Meyer, but this works. At least, for now.

  3. Diane Vigil says:

    More information at Position is Everything.

  4. Diane Vigil says:

    One last comment: it's also helpful to ensure that your layout width is an even number; 780px is good, while 781px will give you problems.

  5. Kathy Moore says:

    My eyes are glazing over :) . I tried your first solution, but what happened then was my background shifted completely to the left margin for some reason. I'd love to try your second solution, but it went over my head. I'd be eternally grateful for a bit more detail on how to utilize that solution.

    Thank you for any help you can give!

  6. Diane Vigil says:

    Okay; not sure what the problem might be without a link to your site. :)

    One tip: make sure your background width is an even number (not, for instance, 781px).

  7. Kathy Moore says:

    Well, I sort of got creative with the one I was working on before but now I am back and here is the URL:

    http://www.scrapkitchen.com/shop

    The header table, in IE, is one pixel off to the left and I just don't understand the div thing well enough to fix it. The stylesheet is already pretty complicated and I know just enough to change what I have to, but I just can't figure this one out. Any help is appreciated. Oh, and the background width is 900px in all places.

    Thanks!

  8. Diane Vigil says:

    I haven't looked closely at it, but:

    – set a fixed width for the table, and add margin:auto

    That alone may fix it. However, if you're adding margins around the table, then IE does … interesting things.

  9. Kathy Moore says:

    Okay, the table is an ImageReady sliced table. In the place where the width is set, it doesn't seem to like margin (I'm using Dreamweaver and it suggests things that belong and margin is not one of them so I am assuming that means it's not a valid attribute in that particular place). I did find the style in the stylesheet and added margin:auto, but that didn't help. I also set it to a fixed width, but nothing there, either. I even added a around the image table only with what you suggested and that didn't do it, either. I swear I'm taking a class soon on CSS, but right now, this is so frustrating! Why can't they all just show it the same way?!?!?

    Let me know if you want to see any files, I'll happily send them to you.

    Thanks!

  10. Kathy Moore says:

    Okay, I finally found an answer and since it is specific to the stylesheet and script I was working with, I won't leave it here. I just wanted to let you know so you didn't spend any more time trying to figure it out for me.

    Thanks!!

  11. Diane Vigil says:

    I know what you mean about browsers; unfortunately, that's just the way it is right now. At least they're closer in display than they used to be.

    Glad you found a way to sort it out. :)

  12. Jeremy says:

    Thanks much for this. Helped me out on a problem I was having!

  13. Diane Vigil says:

    You're very welcome. I'm glad it's helped.

  14. David McNee says:

    Hi Diane, I tried the fix but it doesn't seem to work for me. Could you have a look and see if i'm doing something wrong.

    http://www.neilstontrust.co.uk/home.html

    Thanks

  15. Diane Vigil says:

    Hi David. I haven't looked closely at your code, but I would take a look at your widths on the wide images and the borders.

    In essence, if an image is 800px, then the border around the whole thing probably ought to be 802px.

  16. David McNee says:

    Thanks for replying Diane.

    I've got the vertical border image at 798px and the wide images are at 796px.

    "html>body {margin:0}

  17. Diane Vigil says:

    Excellent. Did that work for you?

    By the way, I always do this:

    body {margin:0; padding:0}

  18. David McNee says:

    Hi Diane
    Managed to get the fix to work for IE but everything shifted 1 px to the right in other browsers. Fixed the problem though using a separate style sheet for IE.
    Cheers
    David

  19. Mike says:

    GOD BLESS YOU!!! IT WORKED!!!

  20. Diane Vigil says:

    You're very welcome, Mike. :)

  21. Kevin Estep says:

    Here is another fix for you that is even simpler. If you make the image 3000 pixels wide (too wide for any monitor) and put the bg image in the center of it then it wont jump around with the resizing of the browser. The background image is actually floating when the browser window is wider than the background image itself. So if you make it way too wide then it will not float because you cannot reach the width of the image with the browser.

  22. Diane Vigil says:

    True. On the other hand, I'd think it would depend on the size of your background image … if it's not just a few K in size, then you may be requiring people to download a huge image just to get your background straight. But it's a solution.

    On the other hand, paraphrasing what I said above: if you do not have to split up the header image, then it's best to ensure that the header image is an even number of pixels in width … that is, 900px rather than 931px. This tip may save you from unnecessary craziness.

  23. jade cloward says:

    Thanks! This fixes IE issue.

    Note: push left or right.
    margin-left:1px} <= for IE
    margin-right:1px} <= for IE

    ———————
    body {margin:0; padding:0; font-family:etc;
    background: #fff url('bk.jpg') center repeat-y;
    margin-left:1px} <= for IE
    ———————

    Never had this issue until today.
    Thanks.

Have your say ...

First-time comments will be held for moderation (but comments are appreciated). Otherwise, just be courteous. If your name is a bunch of keywords, your comment will be deleted. Don't post links unless highly pertinent. Posters must be 16 or older.

Manage your subscriptions

Archives
© 2004-2017 DianeV Web Design Studio. All Rights Reserved.
34 queries. 0.245 seconds.