Centering a Body Background Image that Behaves

So we had ourselves a little bit of a CSS problem here on Script & Style. I wanted to have two “halfs” of the side. The left half with the gray background and the right half with the red background. Easy enough usually, I handle that kind of thing with a background image (sort of like “faux columns”).

On Script & Style though, I wanted these colors to extended to the browsers edge, not be cut off by another wrapper or anything else. Again, easy enough, I’ll just make a background image for the body that is ~2000px wide and center it on the body. That’s exactly what I did: see background image.

So what’s the problem?

The problem is that when the browser window shrinks, the body element shrinks as well. And then because that image is centered on the body, we have an “intrusion” problem:

How we fixed it

We knew about the problem all along, and honestly, I didn’t think there was a good solution for it. I had done a tutorial about half and half backgrounds in the past, but they made use of absolute positioning which would almost certainly cause some z-index problems with our centered site.

The most intuitive solution would be applying a min-width to the body element. After all, this would prevent the body from shrinking any smaller than you set it to and prevent any intruding. I definitely tried that, but it didn’t seem to work.

The nice folks over at Markup Service (one of our PSD to HTML conversion sponsors) noticed the problem too and they emailed me a solution:

html { background:#000; }
body { min-width:958px; }

Huh? How’s that supposed to work? I have tried the min-width thing on the body before to no avail. How is adding a background color to the html element going to change anything. Well, I’m here to tell you folks, it does matter. I don’t know why, I’m not sure I care why at this point, it does the trick!.

With these things now added to our main CSS file, the centered body background image does it’s job. It stays centered, but when the browser window goes to small, it stays in place and doesn’t intrude over to the left.

Comments

Wow cool hack, didn’t know that one.

Nacho | October 9th, 2008 @ 5:04 pm

I’ll second that - nice hack. I’ve never heard of this either but I’m eager to give it a shot.

Thanks for sharing!

Leif Miltenberger | October 9th, 2008 @ 10:55 pm

Unbelievable that it works…so weird.

frank | October 10th, 2008 @ 11:24 am

Would love to know why this works?

Steve | October 10th, 2008 @ 12:56 pm

That’s so weird. I wouldn’t think that a background element could change how the entire page behaves.
I’ll definitely be using this in the future.

Clinton | October 10th, 2008 @ 6:52 pm

Very cool trick and btw I have not told you before Chris but cool website :D

Jermayn | October 10th, 2008 @ 11:44 pm

Does this work cross browser? If so, then it can’t be a bug. It would be interesting to find out why this works.

Joomla Developer in Perth | October 12th, 2008 @ 6:13 pm

Great Solution… It actually gave me a possible solution for a problem I was having with a floating menu. Swicked

Steve the Great | October 13th, 2008 @ 7:10 am

A pure weird thing :D
But actually usefull. Nice! Thanks for sharing.

Laurent | October 15th, 2008 @ 6:27 am

The reason this works is exactly how it is described in the CSS color spec:

For HTML documents, however, we recommend that authors specify the background for the BODY element rather than the HTML element. For HTML documents whose root HTML element has computed values of ‘transparent’ for ‘background-color’ and ‘none’ for ‘background-image’, user agents must instead use the computed value of those properties from that HTML element’s first BODY element child when painting backgrounds for the canvas, and must not paint a background for that BODY element. Such backgrounds must also be anchored at the same point as they would be if they were painted only for the root element. This does not apply to XHTML documents.

LPent | October 28th, 2008 @ 9:15 am

Perhaps I should clarify my comment above a bit more, the spec can be hard to read. ;-)

What it says is that when you do not declare a background property on HTML, anything you declare on BODY will be rendered on HTML. Once you declare something on HTML as well, anything declared on BODY will be rendered on BODY.

So it is not a bug, it is standards behaviour.

Hope this clears it up?

LPent | October 28th, 2008 @ 11:27 am

This is no weird at all. Actually it would be a bug if this did not work. It is very logical. The body can’t be less that a certain width so the background should stay fixed at that width.

Alex Cohaniuc | October 29th, 2008 @ 12:12 pm

@Alex:

Actually, you can set the body to 0 if you want, and the background would hide if you set the html background to something.
You would have to set all content to “relative” or “absolute” though in order to have a functional page.

LPent | November 12th, 2008 @ 4:48 pm

I had the same problem a while back with my old design:
http://www.vileworks.com/firefox-and-opera-background-image-bug

This is another way to fix it:
body {
width: 100%;
display: table;
}

Stefan | November 14th, 2008 @ 12:58 pm

I’ve also noticed that when something doesn’t work as planned in the CSS by adding a border (all, top, left, doesn’t matter) seems to help. I suppose it works as in the case with the hack above. Weird.

Hugo | November 19th, 2008 @ 2:22 pm

Leave a Reply