The difference between <html>
and <body>
is easy to overlook. It seems to be one of those things that falls into the category of trivial. Admittedly, I have a bad habit of applying all global styles to <body>
and, when that falls short, I move to <html>
without thinking about it.
There are differences, however, and it’s a good idea to be aware of them regardless of whether we’re CSS veterans or rookies. We’ll go over those in this post and consider some practical applications where styling one over the other might make sense.
How HTML and body are related
Consider this standard structure for a basic HTML document:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Metadata and such -->
</head>
<body>
<!-- Where the content begins -->
<body>
</html>
The spec defines <html>
as the root element of a document, and we can clearly see that in the above example: the <html>
element is the very top level of all other elements. The buck stops there because there are no more levels beyond that from which styles can be inherited.
From there, <head>
and <body>
make up the only two elements that fall directly inside <html>
. In fact, the spec defines <body>
directly in contrast to <head>
since those are the only two elements that need to be distinguished.
So, the bottom line here is that <html>
is the root element of a document where <body>
is a descendent contained within it. In fact, there is a :root
selector in CSS. These target the exact same thing:
:root {
}
html {
}
Except :root
has a higher specificity: (0, 0, 1, 0) vs (0, 0, 0, 1).
<html>
, right?
So we should always put global styles on It’s tempting to think that any styles we want to be inherited across the board should be applied directly to <html>
because it is the root element of the document. <html>
supersedes <body>
in hierarchy, so it follows that it must contain all global styles.
But that’s not exactly the case. In fact, inline attributes for the following were originally assigned to <body>
in the spec:
- background
- bgcolor
- marginbottom
- marginleft
- marginright
- margintop
- text
While these attributes are now considered obsolete, the recommendation is to use CSS instead with their corresponding CSS property:
Inline Attribute | CSS Property |
background | background | bgcolor | background background-color |
marginbottom | margin-bottom |
marginleft | margin-left |
marginright | margin-right |
margintop | margin-top |
text | font |
Given that these CSS properties originated from inline attributes that were written for <body>
, it would seem appropriate that they should be applied directly to <body>
in the CSS as well, rather than pushing them into the <html>
element.
<body>
, right?
So we should always put global styles on Well, not exactly. There may be situations where it makes more sense to apply styles to <html>
instead. Let’s consider a couple of those scenarios.
rem
units
Working with The rem
unit is relative to the document root. For example, when writing something like this:
.module {
width: 40rem;
}
that rem
unit is relative to the font-size
of the <html>
element, which is the document root. So, whatever is set as the user-default at the root level is what the .module
class will scale to.
Jonathan Snook has a classic post that nicely illustrates how setting the font-size
on <html>
as a percentage can be used as a reset when working with rem
units.
background-color
Quirky There is a weird thing in CSS where the background-color
on <body>
floods the whole viewport even if the metrics of the element itself don’t cover that whole area. Unless the background-color
gets set on the html element, then it doesn’t.
If flooding is the goal, it can be smart to just set it on the html element to begin with.
Wrapping Up
Hopefully this sheds some light on the key differences between the use of <html>
and <body>
in CSS. There are JavaScript differences as well. For instance you don’t need to query for either, html is document.rootElement
and body is document.body
.
We could certainly draw more technical distinctions between the two, but the point here is to level-up our understanding to make better decisions when writing CSS.
Do you have other examples of where it makes more sense to style one over the other? Or perhaps you have a different set of criteria for knowing when when to style one? Let us know in the comments!
Normally I tend to throw background-color on the html and use the body as a wrapper.
That way I don’t need to define an extra div-container with a class of “wrapper” or something.
Also thanks for mentioning the thing about :root having a higher specificity than the html selector. Didn’t know that! <3
Cheers.
Well I feel like a dope. It had never occurred to me to use body as a wrapper. I guess I had always assumed was sacred and should never be used for dirty ol’ styles, and that should only ever hold background and font styles, never margin, etc. I don’t know where I came up with those theories, it’s just one of those things when you never see them utilized otherwise in the wild.
I used to use the body for background color and the main element for wrapping, but then I discovered that the main element should be mapped to the main ARIA role for accessibility. So I moved to using a div.container. I never thought to use body as the wrapper. Interesting…
Unless you make a very basic personal blog and know what you’re doing – using body as a wrapper is crazy awesome. You could even go nuts and start showing the title element as visible page title!
Ok, that second one is over the top and not supported by all browsers.
But, as soon as you move to websites that need more capabilities you will have to move to using a different wrapper element. Unfortunately there are too many issues with for example 3rd party image viewers and html dialogs. Also, what if you need one page where one row has to be full width again?
Trying to fix all that will give a website nobody would want to maintain.
The idea of using the body as a wrapper is good! I really like it, I will be implementing it on my future websites.
I like your thinking. It always rubs me the wrong way when I see
<
div class=”wrapper”> right after a BODY tag.
Rene, you have a point about the full-width thing, but I have not ever had issues with body-as-wrapper and third-party js, and I have used it on medium to large scale sites.
The
document.rootElement
returnsnull
when thedocument.documentElement
returns thehtml
element.When is that the case?
This. I agree,
document.documentElement
returns thehtml
element.https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement
I’m seeing the same it OS X/Chrome 42.
https://dl.dropboxusercontent.com/u/67362/latest-chrome-rootElement-docElement.jpg
I didn’t know
:root
had a higher specificity thanhtml
and had always wondered what the difference was. Great tip, Geoff.Not sure where
document.rootElement
is coming from, but it is not returning the<html>
element. (I’ve tested in Chrome, Firefox and Spartan.) The standard property rather isdocument.documentElement
(see DOM spec).Interesting. I’m sure
document.rootElement
used to work in Webkit/Blink. Now it shows up in the console as a property in the auto-complete, but has anull
value.Regardless, as others have said, the standard DOM property is
document.documentElement
.html {
transform: translate(-60px, 0px);
}
@philtune I guess it is kinda sacred because it is a wrapper you cannot remove, so, all your pages must inherit its style. If you throw a .wrapper div in there you may opt out.
But regarding basic styles like background, font style, etc, I agree. That’s what body is for..
Except it’s easy to throw a class on the wrapper itself to differentiate between the needs of different pages. You can apply basic styles to the body element and then make tweaks with classes like .body-home or .body-about.
I think what he means, is if you want an image to span the entire viewport width, and then text to have a set width, you will end up adding that extra wrapper item in the HTML.
If it’s a basic website, then sure.
html
head
body
header
.wrapper
main
.wrapper
img
.wrapper
footer
.wrapper
Setting background color on the html tag seems to apply very early in the rendering process and if you have alot of includes going on in the head section before the body section then your page will render with the background color before the other stuff loads.
Good point. I’d count that as another argument for putting your page background style on
<html>
. So that you have more of a feeling that “something is happening here”.I often put
to prevent page width from “twitching”. Do you guys think
html
is the right element for this rule?Yes. There is no element that can overlap the default scrollbar so it’s really a scrollbar on the root of the page(window even).
You could opt for using :root instead but that’s just the same anyway.
I generally use the html tag for sitewide stuff (just like modernizr classes) and the body tag for page specific classes, if that makes sense.
I tend to put height and width of the body together with the html tag when I’m doing a site fixed to the window size.
In the quirk regarding background colors you say:
This conclusion seems to contradict the first statement. Am I reading this right, or misunderstanding something?
Answered below.
thanks god.. this is something simply i didnt know
http://klinikkandungananak.com
Even Google has html/css error…
http://www.richard-visav.com
Nice link spam there. Don’t expect me to click it.
Perhaps worth mentioning that the background color on html influences the color of the scrollbar in safari for mac. This can be confusing if you have a absolute positioned sidebar with a white background by the scrollbar, while the html background is black. Will render the scrollbar almost invisible (white on white). http://codepen.io/anon/pen/ZGzgPg
Wow, had no idea Macs render scrollbar color dynamically…
Thanks for this post, very interesting stuff. Never heard of root: so I’ll be sure to look into this a little more.
I’m confused. You said ‘There is a weird thing in CSS where the background-color on
<body>
floods the whole viewport … If flooding is the goal, it can be smart to just set it on the html element to begin with.’???
If you have a BODY element that doesn’t take up all the same space as the HTML element and you set a background-color on the BODY and no background color on the HTML element then that background color will fill the whole page (which presumably is the same dimensions as the HTML element), meaning that this quirk causes the background color set on the BODY element to behave as though it had been set on the HTML element. Soooo… if your BODY element doesn’t take up all the same space as your HTML element but you want one background color to cover everything the HTML element covers then it makes slightly more sense to set the background color on the HTML element rather than relying on the quirk to do the work.
The specs explicitly state that a background on the body element should be propagated to the html element (when no background has been set on html) and therefore there is no need to specify the background-color of the html and indeed it is recommended for authors of html pages that they specify the canvas background for the body rather than html.
http://www.w3.org/TR/css3-background/#body-background
It is not a “quirk” as such but an important part of the specs.
I believe that in ‘most cases’ the only properties you want to set on html are font-size, reset margin/padding, box-sizing and occasionally height (for 100% layouts). Other than that simply leave it alone for best results.
Also using the body as a wrapper was historically bad and caused all sorts of problems in ie7 and under and although those browsers aren’t an issue theses days there are still problems with zoom in newer versions of IE so again I think that for the sake of one wrapper element you can avoid all these issues in one fell swoop.
The one thing about using body as a wrapper instead of, say, a div, is that sometimes you want to nest things in the body outside of the main constraints of the document. Content on the margins, for example. If you’re thinning down the body to, say, 75% of the viewport, you can still add content to the margins but it’s going to result in some very ugly code.
Believe it or not, people knew what they were doing when they pushed the sacredness of the body. Using other elements to comprise the main boundaries of the content (I suggest using three or four – header, footer, and article…then, maybe, nav as a fourth or as a part of the header &&/|| footer &&/|| article.
A lot to discuss here.
html { height:100% }
body { min-height:100% }
Correct me if I’m wrong, but I see a contradiction on the text:
“There is a weird thing in CSS where the background-color on
<body>
floods the whole viewport (…) Unless the background-color gets set on the html element, then it doesn’t.””Untill here, all fine, but then, you say:
If flooding is the goal, it can be smart to just set it on the html element to begin with.”
This same concern has been answered elsewhere in this thread.
I use
<body>
for all global styles for one specific reason: I use<html>
as a sacred element that I never apply custom styles to, so that I can make calculations based upon it in JavaScript knowing that I’m not messing with its attributes somewhere in the mix of CSS. It’s helped me more than once, but might not be a necessity for some.