This is actually an old version of danielmall.com. For the latest and greatest, check out the new site.
 

Well Educated CSS

Few CSS designers take advantage of the <body> tag. However, like most tags, the <body> can receive id and class attributes. When used appropriately, taking advantage of these attributes can help to create some very efficient sites.

When creating a full fledged site, it’s often useful to determine how many unique page types are required for the site, that is, how many different layouts need to be designed and built. This is directly related to creation of templates, specifically beneficial to sites managed with a CMS. Certain types of sites, such as blogs or e-commerce sites, lend themselves very well towards templating. It’s no coincidence that the most popular blogging engines—such as Movable Type, ExpressionEngine, Wordpress, and many others—work this way.

Even in taking a large site (in terms of the quantity of pages) like Gap.com, it’s easy to see how the whole site is built on a set number of unique page types.

So how can Well Educated CSS make a site with templating similar to this more efficient? Let’s examine the power of semantic markup. On the most basic level, the id attribute should only be used once per page. It’s used to identify a single instance. However, designers are encouraged to leverage multiple uses of the class attribute to similarly style different elements on the same page.

To capitalize on this, think about it on a site-wide level. If all articles on a site should look the same, why not give those pages the same class of "article"? This method effectively groups similar pages and allows instant sitewide changes, capitalizing on the power of CSS.

And let’s not forget about the id attribute. Almost painfully obvious, use id to identify sections. In terms of the site information architecture, if your site has 3 main top-level sections—Home, Blog, and Portfolio—then it might make sense to id each section as such. Why is this useful, and, more importantly, why is it practical? One of the easiest things that you can do with this approach is color-code specific sections. You can write rules that look like this:


body#home { color: red; }
body#blog { color: blue; }
body#portfolio { color: black; }

This approach is very useful in making section-wide changes, taking direct advantage of the global nature of CSS.

In essence, this method makes it extremely easy to change the layout of the page, solely by changing or adding a class on the <body>. Here are three examples of pages that have identical markup, with the exception of class and id attributes on the <body>. You’ll see that each page has a distinct layout, all dictated by the CSS:

Short of being a programming language, this may be the closest you can get to conditionals within a CSS file (without using a server-side scripting language). This rule:


body#blog.article { color: black; }

becomes English as:

If the body tag has an id of “blog” and a class of “article”, all text should be black.

…which could translate in a programming language to something similar to:


if((bodyID == "blog") && (bodyClass == "article")){
//make all text black
}

The possibilities are endless; by making some strategic decisions about your coding before you begin, you can create a flexible framework that is extremely simple to work with.

Comments

Matthijs said:

This methodology is indeed very useful. One tip I would like to add: be careful if you start using this for more general layout elements. Otherwise, if your layout is getting complicated you'll get unexpected surprises. For example, if you use a rule like #home ul { } suddenly your previous general rule of .side ul { } is being overruled.

Posted on May 17, 2006 04:01 AM

web said:

Dan this is huge, I use this often and its super useful.

Another tactic along the same line is using multiple classes separated by spaces to apply different levels of formatting to elements.

Posted on May 17, 2006 07:31 AM

Jared Christensen said:

Great tip! I have used this to create entireley different styles on my homepage while still using the same classes and id's found on all my other pages. It's also great for creating "you are here" navigation systems or any other feature that would change depending on the page you're viewing.

Posted on May 17, 2006 10:28 AM

Dan Mall said:

Awesome additions, guys!

@Web: Multiple classes are definitely more difficult to manage, but they can add a great level of specificity without having to resort to advanced CSS.

@Jared: Good point; I forgot to mention that. It’s also useful for showing sub-navigation per page type rather than having to specify exactly which subnav shows on which pages.

Posted on May 17, 2006 10:39 AM

bearskinrug said:

Helpful, tips Dan! Although I constantly struggle with syntax, I think I can remember this dealy!

Posted on May 19, 2006 08:23 AM

Tim said:

Dan, I do understand the benefits of such an approach CSS wise, but don't get what you mean by:

if((bodyID == "blog") && (bodyClass == "article")){
//make all text black
}

would you mind explain a bit more ?

note: the live preview and allowed HTML tags in comments are a great match !

Posted on May 19, 2006 09:48 AM

trovster said:

Every site I add the site's URL as the id on the body. id="www-danielmall-com" which gives users the ability to restyle the site.

Then I add multiple classes like 'Web' said. class="section page" which allows targeting the navigation states, styling sections and targeting specific pages.

Posted on May 19, 2006 11:18 AM

Thomas Higginbotham said:

I hope I'm not stepping on your toes, Dan, by answering Tim's question but, basically, the code is pseudo-code (possibly JavaScript or C) for what the CSS is doing. In simple English it means "If the body tag has an ID of 'blog' and a class of 'article', then make all of it's text black."

I hope that answers your question.

Posted on May 19, 2006 12:44 PM

Tim said:

Thx Thomas.
I was thinking of some programming gurus that would generate different templates based on the id of the body tag, and was wondering what advantages this would bring.
Now I see how this could be useful...

Posted on May 19, 2006 02:37 PM

Dan Mall said:

@Thomas: You're not stepping on anyone's toes. Thanks for answering that!

@Tim: In theory, the CSS eliminates the need for any object-oriented code and essentially does the work for you. Instead of JavaScript or PHP generating different templates based on the <body>, the CSS will perform the same functionality.

Posted on May 19, 2006 02:56 PM

depi said:

Hi!
Thanks for these really good tips, it is a good idea, I may try it on the next page I will do.

Posted on May 19, 2006 03:30 PM

brx said:

i cannot see the advantage for this:

body#blog.article { color: black; }


achieve the same with this:

#blog .article { color: black; }

you don't need 'body'

Posted on May 19, 2006 04:59 PM

Dan Mall said:

@brx: Code-wise, there's no advantage to the specificity. However, from a maintenance and readability perspective, it's much easier to recognize that "blog" is an id on the <body> rather than identifying a <div> or other element. I know that's a matter of preference, but it's a convention that I usually stick to and has worked for me in the past.

Posted on May 19, 2006 05:09 PM

Daniel Webster said:

This is a nice tip for those learning to code web pages for the first time, but isn't this basically the whole point of using CSS in the first place? It seems to me that this principal is fundamental to the concept of separation of content and style.

Posted on May 19, 2006 07:13 PM

brx said:

@dan

but every element is a child of ...why mention it again and again? it makes IMHO no sense

Posted on May 19, 2006 07:30 PM

brx said:

a child of body (body was ripped out in my message above)

Posted on May 19, 2006 07:32 PM

Dan Mall said:

@Daniel: Yes! You're absolutely right. It took me a while after first learning to write CSS to understand the concept of the cascade and writing rules in conjunction with each other. It's not a new or cutting edge concept by any means; I just thought it was worth emphasizing for those that may not be very familiar with the technique.

@brx: Every element that can be styled is a child of the <body>, but I think you may have misread the syntax. The difference between "body #blog" and "body#blog" (with no space)is that the first targets a child element of the body with an id of "blog", and the second targets the body with an id of "blog". Similarly, "body #blog .article" (with spaces) targets an element with a class of "article" inside an element with an id of "blog" inside the body, whereas "body#blog.article" (without any spaces) targets the body tag with an id of "blog" and a class of "article".

Markup wise, what you're describing looks like this:

<body>
<div id="blog">
<div class="article">
</div>
</div>
</body>


and what I'm describing looks like this:

<body id="blog" class="article">
</body>


Hope that clears it up a bit.

Posted on May 20, 2006 09:00 AM

Fredrik Wärnsberg said:

I actually never thought about this, but it makes perfect sense. I guess I'll be using this for my new blog!

Thanks for the tip!

Posted on May 21, 2006 04:27 PM

Damien said:

Good article. I started using id and class selectors on body tags a while ago and wish I'd done it when we did the current iteration of our home-pageas its CSS is now ver unwieldy. But, you live and learn and with every site, get better - I hope, lol.

Posted on May 22, 2006 01:55 AM

Nicolas Hoizey said:

Like trovster, I use the same body id on all pages of my site so that people can personalize the look (for accessibility mostly).

I may add classes, it a good idea!

Posted on May 22, 2006 04:28 AM

SeB said:

thanks... youve got a comment in my css style sheet :)

Posted on May 22, 2006 11:05 AM

Asif Shahidullah said:

Very interesting, I'll be sure to try it out some time, however, the line

html>body

What does this mean? I've seen something like this before, but I am unsure what it does. Can anybody help?

Posted on May 22, 2006 03:12 PM

Dan Mall said:

@Asif: The ">" targets direct descendant selectors. The rule that you wrote means "any body tag that is a direct child of an html tag", which should hold true in every browser. However, Internet Explorer 6 and under don't understand the descendant selector, so it's basically a way to target all browsers except IE. For the way I've always used it, I'll write a rule without the "html>body" for Internet Explorer, then write a rule just below it with "html>body" for progressive browsers. The benefit of using it is that it doesn't target browser bugs; it targets browser support. In other words, it doesn't target specific browsers, just browsers that understand that rule.

There's a great article by Eric Meyer called the The Child Selector, as well as from Maxdesign called Descendant Selectors. Both are definitely worth reading.

Posted on May 22, 2006 03:29 PM

beejamin said:

Trovster: Be careful - valid ID's, as far as I know, can only contain alphanumeric characters. I don't believe the underscore is even valid.

I have had browsers behave weirdly before when using ID's with invalid characters.

Posted on May 22, 2006 10:58 PM

Ponijs said:

You're misusing the word "tag".

Posted on May 23, 2006 05:26 AM

GreenLantern said:

Excellent article. I never thought of coding my CSS this way. Thanks.

Posted on May 23, 2006 11:24 AM

trovster said:

beejamin: I'm afraid that's where you're wrong.

First of all I used a hyphen, not an underscore, however, both are valid.

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

From the HTML 4 specification.

Posted on May 31, 2006 11:47 AM

雷区 said:

I can not understand it will be better if you can give us a few examples.

Posted on June 17, 2006 10:04 AM

Some1 said:

Trovster: You pulled that from the HTML spec...really you should have grabbed something from the CSS spec. Although non-alphanumerics make for valid id's as far as HTML is concerned, using them is things meant to be styled by CSS is problematic. It is not possible to say 'div#www.thing.com' and have the right thing happen. You can say 'div[id="www.thing.com"], but support for this syntax is flakey under IE, at best. So by using these non-alphanumerics in your id's, you're kind of shooting yourself in the foot if you care about CSS stylizability. By way of example:

thing.html:
<html>
<head>
</head>
<body>
<div id="thing">thing</div>
<div id="thing.thing">thing.thing</div>
<div id="thing:thing.thing">thing:thing.thing</div>
<div id="thing:thing:thing:thing">thing:thing:thing:thing</div>
</html>

thing.css:
#thing {
font-size: 160pt;
}
div[id="thing.thing"] {
font-size: 80pt;
}
div[id="thing:thing.thing"] {
font-size: 40pt;
}
div[id="thing:thing:thing:thing"] {
font-size: 20pt;
}

...so try it out, '#thing' is valid, but you you try to do '#thing.thing', it won't work, and it's possible that only the first CSS rule will work under IE.

So yes, while an id may technically, as per HTML spec, contain non-alphanumerics, if you care about CSS, it is in your own best interest not to use them.

Posted on September 1, 2006 08:17 PM

Sorry: comments are closed.