HTML vs Body in CSS

Avatar of Geoff Graham
Geoff Graham on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

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).

So we should always put global styles on <html>, right?

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.

So we should always put global styles on <body>, right?

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.

Working with rem units

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.

Quirky background-color

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!

More resources