View source on almost any web page and you’ll likely see the following:
<html>
<head></head>
<body>
<div id="wrapper">
<!-- All the things -->
</div>
</body>
</html>
The use of a wrapper or container div
around the page is fairly universal. It is commonly used to perform tasks such as centering a page’s content or providing a shadow or border to frame it. But, since the body
element is a necessity in the markup, why can’t it be styled directly instead? Why is a wrapper div
used?
Historically there have been a number of issues with using the body
element as a top level container in old versions of Internet Explorers. If you’re supporting IE >= 8 you’re good, but there are some things you should be aware of.
IE 5.5
To get to the origins of the wrapper div
let’s go way back. A pretty common practice is to center the top level container using margin: 0 auto
, and this works fine in all browsers… back to IE 5.5. IE 5.5 did not support auto
margins so this approach did not work.
To center the top level container in IE 5.5 you had to make use of text-align: center
as such:
body {
text-align: center;
}
#wrapper {
width: 1000px;
text-align: left; /* counteract the declaration on body */
}
text-align: center
should only affect inline elements, but IE 5.5 incorrectly applied it to block elements as well. (Note: The text-align: center
bug was fixed in IE6 standards mode, but the behavior remained in Internet Explorer’s quirks mode to this day.)
IE6
IE6 implemented auto
margins, so margin: 0 auto
was now safe to use on the body
. Additionally, IE6 fully supports adding a width
, padding
, margin
, and border
to the body element. Take the following CSS:
body{
width: 90%;
border: 2px solid red;
background-color: black;
color: white;
padding: 10px;
margin: 0 auto;
}
The layout renders the same in IE6 as it does in the latest version of Chrome (23 as of this writing).
Believe it or not using the body
element as a top level container is actually safe in IE6.
IE7
If there are no issues with IE6 why am I still writing? IE7 introduced a feature new to Internet Explorer, zoom, and with it came a new bug.
When a margin
or width
is applied to the body
and the user zooms, IE7 incorrectly treats the left edge of the body
as the edge of the viewport. This shift bumps content on the right hand side of the page outside of the screen. The image below shows the result of a zoomed in window and styled body
in IE7.
This issue is not present using a wrapper div
.
Beyond IE7
In my testing beyond IE7 there are no major issues using the body
element as a top level container. There are however a few things to be aware of.
Positioning
Any absolutely positioned elements will be positioned relative to the viewport rather than the newly placed body
. To fix this set position: relative
on the body
as such:
body {
margin: 0 auto;
width: 90%;
position: relative;
}
Backgrounds
Backgrounds applied to the body
will take up whole page regardless of margins. Consider the following:
body {
background: black;
margin: 0 auto;
width: 200px;
}
The screenshot below shows this. The background of the entire viewport is black rather than a centered 200px block.
This can be worked around by applying a background
on the html
element:
html {
background: white;
height: 100%;
}
body {
background: black;
margin: 0 auto;
width: 200px;
min-height: 100%;
}
Note the height
that was added to the html
element and the min-height
added to the body
. This ensures that the background
applied to the body
element will take up the entire height of the screen.
The rules above will now render as expected:
scrollHeight and scrollWidth
In WebKit based browsers the body
’s scrollHeight and scrollWidth properties are unaffected by declared height
and width
styles. For example:
<html>
<head></head>
<body style="height: 200px; width: 200px;">
<script>
console.log(document.body.scrollHeight);
console.log(document.body.scrollWidth);
</script>
</body>
</html>
This will log 200
for both in all modern browsers with the exception of WebKit based ones. WebKit will return the height and width of the viewport.
While you are unlikely to run into this directly, you may use a library that does. For example, this causes an issue trying to constrain jQuery UI draggables within the body
.
Is it Safe to Use Yet?
The zoom issue in IE7 is bad, but if you’re no longer supporting IE7 it’s safe to drop the wrapper div
and style the body
directly.
That being said, there’s no harm in leaving a wrapper div
in place. So if you have any doubt stick with <div id="wrapper"></div>
.
Know of any other bugs with styling the body
element? Let me know in the comments.