One thing any good developer will tell you is that efficiency is key. Whether that be workflow, the code itself, or just achieving a single goal. Invest a little forethought at the beginning to save a lot of time later. I like to think of it as being cleverly lazy. One great example of this is by simply utilising the id="" attribute on the <body> element. Yep, really, something as simple as that.
The concept
The concept here couldn’t be more simple. You really are just adding an id="" to the opening <body> tag, that id="" is specific to—and representative of—that page. So your homepage might look something like this: <body id="home">, your about page: <body id="about">; contact page: <body id="contact"> and so on.
The idea of per-page <body> id=""s is not a new one either, it’s been around a while, yet is still annoyingly under-utlised. I’m pretty certain you’ll love them as much as me after this tutorial. They’re the future, honest.
The code
Using PHP, for good measure.
If you (and you should!) use includes to pull in your header containing that opening <body> tag then you obviously can’t write a different id="" into each page. So, I’ll show you here how to get this method working with PHP includes too:
<?php
$pageID = 'home'; /* Define the ID variable */
include('/includes/header.php'); /* Include the header */
?>
<div id="content"> <!-- The page's content -->
<h1>Welcome to our home page!</h1>
</div>
<?php
include('/includes/footer.php'); /* Include the footer */
?>
Above: a very basic example of a page built with PHP includes.
This is our homepage, we set the page’s <body> id="" via the PHP variable $pageID. Next up, we grab the contents of that variable (home) and use it in the header.php include that we reference. That header.php include looks like this:
<!-- Other HTML in the <head> -->
</head>
<body<?php if (isset ($pageID)) { echo ' id="' . $pageID . '"' } ?>>
The above PHP checks if you have set a variable called $pageID (if (isset ($pageID)) {) and then if you have, it then writes out id="YOUR_ID_HERE", if you haven’t then nothing happens. Our example would resolve to <body id="home">
So now any page you define a $pageID variable on will have an id="" on its <body> element.
Using it…
It’s all well and good creating an id="" for each page, but how do you use it? Well there are, in my opinion, two major benefits and usages of the <body> having an id="". Firstly there’s page specific styling from within one stylesheet, the second is self-highlighting ‘current’ states in your navigation menu.
Page specific styling
Every page has its own ID, every page can have its own styles…
Imagine you have a site where one page need needs to be slightly different in layout to all the others. Let’s say that on the homepage you want your main #content <div> to be full width with no sidebar, and the inner pages you would like the #content <div> to be 640px wide and the #sub-content <div> to be 280px wide. Without per-page id=""s on the <body>, you’d most likely have to have a main style.css and a file called home.css to re-style just the home page. The following excerpts of code are from style.css, home.css and the markup respectively:
/* Code from style.css */
#content{
width:640px;
float:left;
margin-right:20px;
}
#sub-content{
width:280px;
float:left;
}
/* Code from home.css */
#content{
float:none;
width:100%;
}
/* Code from markup */
<link rel="stylesheet" type="text/css" href="/css/style.css" />
<link rel="stylesheet" type="text/css" href="/css/home.css" />
It works, but it ain’t efficient…
This works fine, of course it does, but you now have one more file than before and more markup to include it. Imagine it wasn’t just your home and inner pages you needed styling; imagine your contact page needs another custom style to accommodate a map. Sure, you could make contact.css but then that’s a third file and another line of markup. Where do you draw the line? When every page has its own stylesheet? Of course not, you use <body> id=""s!
Let’s do all that again using a <body> id="" to style individual pages:
/* Code from style.css */
#content{
width:640px;
float:left;
margin-right:20px;
}
#sub-content{
width:280px;
float:left;
}
#home #content{
float:none;
width:100%;
}
/* Code from markup */
<link rel="stylesheet" type="text/css" href="/css/style.css" />
It works and it’s super efficient!
That achieves exactly the same effect as the previous example, but it’s one less file to manage, and one less line to write in the markup to include another stylesheet. That little bit of effort you put in setting up page id=""s is already paying off…
A few real-life usages on the Venturelab site are:
.hr { ... } /* Default <hr /> styles */
#devblog .hr { ... } /* Devblog specific <hr /> styles */
#devblog h1, /* Devblog specific heading styles */
#devblog h2,
#devblog h3,
#devblog h4,
#devblog h5,
#devblog h6{
font-family:'Sketchetica',Helvetica,sans-serif;
font-weight:normal;
}
#home{ /* Homepage specific body styles */
background:url(/img/css/homepage-bg.gif) top left repeat-x #fff;
}
#devblog{ /* Devblog specific body styles */
background:url(/img/css/devblog-bg.jpg);
}
We keep all our styles contained in one style.css file which means we only need one <link /> element in the head.
Self-highlighting menus
The second, and less obvious usage for per-page id=""s is making a self-highlighting navigation menu. Normally (and horribly) you’d apply class="current" to whichever item in the menu is the current page. For this example we’ll assume that the about page is the current page. Old-fashioned style highlighting:
/* Markup */
<body id="about">
...
<ul id="nav">
<li><a href="/">Home</a></li>
<li><a href="/about/" class="current">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
/* CSS */
.current{
font-weight:bold;
}
This method is tried and tested, however that class="current" in the markup is ugly. Also, if you’re using includes for your nav (you should be!) you can’t add a class="" to individual items. Enter the new <body> id="" method. By knowing that whatever the current <body> id="" is, you can use that information to target and style the corresponding menu item, thus:
/* Markup */
<body id="about">
...
<ul id="nav">
<li class="home-link"><a href="/">Home</a></li>
<li class="about-link"><a href="/about/">About</a></li>
<li class="contact-link"><a href="/contact/">Contact</a></li>
</ul>
/* CSS */
#home .home-link a,
#about .about-link a,
#contact .contact-link a{
font-weight:bold;
}
Cleaner but not shorter…
On the face of it that is more code, however you don’t need to add class="current" to the current menu item, which is made impossible by using includes. The code stays cleaner and the cascade sorts everything out for you.
Bonus usage!
If you opted to use the PHP method of defining the id="" then you’re in for a treat here. You can use that PHP variable to write out content to the page. For example:
<?php
$pageID = 'home'; /* Define the ID variable */
include('/includes/header.php'); /* Include the header */
?>
<div id="content"> <!-- The page's content -->
<h1>Welcome to our home page!</h1>
<?php if (isset ($pageID) && $pageID == 'home') { ?> <!-- If it's the homepage... -->
<div id="home-promo">...</div> <!-- ...show this! -->
<?php } ?> <!-- Close PHP -->
</div>
<?php
include('/includes/footer.php'); /* Include the footer */
?>
Here we are using our PHP variable to determine the page, and then run a script based on it. This becomes really useful when you have have content in an include that you can’t add/remove per page, but can programmatically show/hide using the $pageID variable.
Final word
By investing time in setting up a system of using per-page id=""s, you can increase both the efficiency and functionality of your code no end. Try it out, and let us know how you get on.
June 23rd, 2010 by Harry Roberts in Web Development.





Robson Sobral said on June 25, 2010 at 5:01 pm
Hey! Do you accept a suggestion? HTML5 accepts class attribute on html element. This give us one more element to customize!
#home body {}
Graham Ashton said on June 26, 2010 at 7:57 pm
Hi. It’s all great stuff, but have you considered using a class on the body tag instead of an id? By using an id you raise the possibility that somebody else will add markup to the same page containing another element with the same id, rendering your markup invalid.
I can’t see any downsides to using a class instead, which is the only reason that I’m raising it.
Cheers,
Graham
Harry Roberts said on June 28, 2010 at 8:22 am
@Robson: Thanks for that one. We’ve not come across a need for it yet, but it’s definitely worth knowing.
@Graham: I know Wordpress uses classes on the body, however I think an ID is better suited as it’s unique. There’s one home page, one about page etc, so an ID seems, in my eyes, more appropriate. They do still both achieve the same goal, so it’s preference I guess.
Aled said on June 30, 2010 at 2:50 am
EXCELLENT TUT Harry!!!! (As was the tutorial on persisting hover states on dropdown menus using only CSS – I think you have the only tutorial on the web for that. I’m being serious)
:)
kosskoz said on June 30, 2010 at 11:33 am
I don’t like this method at all because I think having a different css per page is far more maintainable than having all our styles in the same file.
I prefer having one css per page than one css for all the website but I think it’s a matter of taste.
By the way, you can use a ternary operator in PHP for inline conditions.
Harry Roberts said on June 30, 2010 at 11:39 am
@kosskoz:
Interesting take. I guess it is, as ever, a case of preference. I however see editing one CSS file and one CSS file only more maintainable than several CSS files and a corresponding amount of markup.
And yeah, I’m aware of the ternary operator, and I was going to use it in the tutorial, but as this is a CSS article and not PHP, I have to assume that readers have no (prior) knowledge of slightly more advanced PHP syntax.
Jon said on June 30, 2010 at 3:41 pm
I agree with what you’re saying completely. Though it doesn’t necessarily need to be in the body, it applies universally. You’re just giving the child elements context.
However, I really don’t agree with using an id. I have no idea why people feel the need to keep using ids in CSS. There’s no benefit. The fact that ids are unique means nothing – you can have a unique class too. They’re enforced to the same degree. I.e. by you. Keep CSS selectors centralised and within the class attribute!
Simon Wiffen said on June 30, 2010 at 3:51 pm
@Jon
Absolutely right. Obviously the technique described here can be adapted to suit your preference. As you say using a class would work just as well. Personally, we prefer the explicit use of a unique id for this purpose. We generally use id’s where we’re referring to a specific context, as we are here. It allows us to scan the css and recognise these instances easily amongst the more generic class names. There’s no right or wrong, use whichever method fits best with how you like to work. Some good discussion going on here, keep it coming :-)
origiNell said on July 11, 2010 at 9:47 am
@Jon
You are totally right. However IDs are rather important from a performance side (rendering engines and javascript). I recently read a nicely conditioned article about that, however I can’t find the link :-S
Anyway, I think it’s kind of logical: when using an ID the browser/javascript engine can be sure it’s hit and miss. IDs are definitely unique, therefore the engine only has to look for one item, at the moment the element has been found, the engine stops and moves on to the next. With classes, which are obviously not unique, the engine has to traverse the markup tree until it is definitely at the end.
Therefore we have some performance differences between using IDs and classes. Granted, the difference is kind of non-existent from a user perspective by todays computing power (even facebook is using a class based system instead of combining it with IDs) but aren’t we developers always thriving for the best performance :D?
I have always been against using IDs and classes on the element.. Actually I don’t know why, but I feel dirty when putting classes or IDs on the body tag. Maybe it’s just rembering of the good ol’ days when we used to do .. I have to say this article convinced me (especially the navigation section).
Keep it up!
Greetings from austria
Tom said on July 11, 2010 at 1:00 pm
While you’re on the topic of CSS you could have bothered to make the code blocks visible on an iPhone. Just saying. Would have like to actually read this article but as I can’t see any of the code it’s pretty useless.
Tim said on July 11, 2010 at 2:04 pm
I recommend using more descriptive ID names like “page-home” and “page-contact” to reduce the likelihood of conflicts for someone else adding to your code. For CSS, I prefer to include HTML elements in the selectors because it’s easier for someone else to interpet without needing to check the HTML.
Enrique RamÃrez said on July 11, 2010 at 4:37 pm
I’ve always coded my sites like this, but the amount of developers that refuse to work with them amazes me. Most of the times I get told that they can’t add an ID to the body tag (of course, it means they don’t want or know how to).
Then again, on my projects and projects I know this will work, I use an ID on my body tag. :) Good to know I am not alone.
cpk said on July 11, 2010 at 8:09 pm
I am a big fan of using IDs on the body tag. You can also uses classes if you like or both in combination. Technically, IDs are single use on a page and classes are multiple use so they should be applied appropriately.
However, one of the main advantages of choosing an ID selector over a class is specificity. An ID selector has a specificity of 1,0,0 and class is 0,1,0. ID selectors have a huge advantage over classes by preventing the need for ridiculously long css declarations in order to override preexisting CSS declarations on large corporate websites built on CMSs like Drupal.
Cornelius said on July 12, 2010 at 1:56 am
I use a system almost exactly like this. Rather than use “home” and “contact” as IDs, I name the page IDs like this: “p_home”, “p_contact”. It’s easy for me to read and I don’t have to worry about stepping on the toes of another similarly named ID.
For the main nav, I DO use a class called “selected” for the current page. But it’s easy to set up in a PHP include when using page IDs. In the nav include file I first set up the page info in an array. Each array item includes all the info I need about that page (page ID, link text, and URL, and class if that nav item needs special treatment). Since I’ve already set my page ID in a PHP variable at the top of the main page, while I’m iterating through the array and building the HTML for the nav, I test whether the current page is the same as the array item I’m on. If so, add the class “selected”. This code doesn’t need to be duplicated anywhere and neither does the CSS which is centralized in the global CSS file. There should be no reason to put page-specific CSS in separate files, or include snippets of CSS in the HTML.
Niels Matthijs said on July 12, 2010 at 7:45 am
While much harder to automate, there are some improvements possible here.
IDs indicate unique elements within a site. Sometimes though it’s better to use the body#id for referencing a section and using the body.class for specifying which page within a section you’re talking about. Some examples:
body#news.overviewPage
body#calendar.overviewPage
body#calendar.detailPage
This way you can style consistently through sections of your site + you can drill down using classes.
Harry Roberts said on July 12, 2010 at 8:06 am
Thank you for all the comments and discussion, it’s great to see.
Tom, this is now fixed.
Cheers all,
Harry
darrinb said on July 12, 2010 at 6:20 pm
To touch upon your comment from 6/30 regarding WordPress and body classes; I prefer to use ids, as I think it gives greater css control as well as greater efficiency with libraries such as jQuery. Automating the process can be a pain though–especially if you’re not coding from scratch. I actually just wrote a function for this for WordPress. I don’t know if you allow links or not (forgive if you don’t): http://darrinb.com/notes/2010/adding-a-custom-id-to-the-body-element-in-wordpress/
James said on August 2, 2010 at 8:51 pm
Thanks for posting, really nice way of creating more efficient code.