Why use Classes or IDs on the HTML element?

Published by Chris Coyier

Reader Nicolas writes in:

I'm frequently seeing ID and class specifications to <body> and <html> elements. I'm curious as to why one would do this? If it is unique to either element, then why not specify body or html in the CSS?

I believe what Nicolas is asking is why would you do this:

<html class="happyNewYear">
.happyNewYear { background: url(/images/fireworks.jpg); }

When you could just do:

html { background: url(/images/fireworks.jpg); }

...and skip the class name. After all, there is guaranteed to only be one <html> element, right?

I see Nicolas' point. If you view source and look at a page in isolation, I can see how any class or ID on the <html> element seems superfluous. The fact is, these top-level classes can be extremely useful. Let's review the theory and see some real word examples.

Many Pages, Few CSS files

The idea of CSS is to abstract design away from markup. One hundred pages on a site may all use the same exact CSS file. This is efficient for many reasons, one of which is that changes to design happen in one place, rather than one hundred. A top-level class can serve to identify which page is currently being viewed and thus apply styling to that a different page may not get.

Different pages, same CSS file, different designs. And because this is happening at the highest level possible element, you can control the entire pages design through a single class hook.

WordPress

A WordPress powered site uses themes to display pages. All pages on the site are built from the active theme. This theme has a file in it called header.php which outputs the top of all the pages, like the doctype, head, and opening body and html tags. WordPress has a function called body_class() which outputs a whole bunch of classes that are specific to the type of page being loaded. Most themes have an opening body tag like this:

<body <?php body_class(); ?>>

On a single post page, the output might be like this:

<body class="single single-post postid-8212 logged-in">

On the homepage, the output might be this:

<body class="home blog">

Now there are a bunch of hooks you can use in the CSS file to style things uniquely based on the kind of page. For example:

.single h2 {
   font-size: 150%; /* Fonts bigger on single post pages */
}
.home aside {
   width: 100%;  /* Sidebar kicked to bottom of page on homepage */
}

I'm not entirely sure why WordPress calls it "body_class", as you can (and it's often useful to) style the HTML element directly. Just as an FYI, you can absolutely just move the function up to the HTML element.

Modernizr

Modernizr is a JavaScript library that also adds top level classes. It adds them dynamically to the html element when it loads and runs. The classes are symbolic of what the current browsers capabilities are. So whereas WordPress applies classes you can use to make different pages look different, Modernizer applies classes you can use to make the same page look different, depending on browser capabilities.

This is what an html element might look like after Modernizr:

<html class="js flexbox canvas canvastext no-webgl no-touch 
  geolocation postmessage websqldatabase no-indexeddb
  hashchange history draganddrop websockets rgba hsla 
  multiplebgs backgroundsize borderimage borderradius 
  boxshadow textshadow opacity cssanimations csscolumns 
  cssgradients cssreflections csstransforms no-csstransforms3d 
  csstransitions fontface video audio localstorage sessionstorage 
  webworkers applicationcache svg inlinesvg smil svgclippaths">

So now you might have CSS that styles things differently depending on the capability:

section {
  background: url(boring-fallback.jpg);
}
.multiplebgs section {
  background:
    url(logo.png) top left no-repeat,
    url(texture.jpg),
    url(top-edge.png) top left repeat-y;
}

Anything else?

I have an older article which covers this same idea and the classic tip of using this idea to do current navigation highlighting. Check it out for some other tips.

Please share if you have some other use-cases for using top-level classes.