Recently I began work on a serious revision to the Minimalist Sandbox, which I released last week. Andy Skelton was nice enough to give me some thoughtful feedback on adding semantic classes to the body and post div elements, pointing out:
[Semantic classes should be used] rather than
.widecolumnand.narrowcolumn, because selectors in markup should be semantic rather than indicative of visual style and because this affords better use of WP’s semantic nature.
Why semantic classes are useful
Let’s begin with the body element. Semantic classes are based on what theme file is generating the page (read about WordPress file hierarchy). On the home page, we’ll get <body class="home"> and then on a single post page we’ll get <body class="single">.
Here’s an example of how these semantic classes could be useful. I have a theme that requires different margins for the post title headings on the home page, i.e., index.php, than on a single post page, i.e., single.php. With the appropriate classes being dynamically generated in the body element, I can add the following CSS:
body.home h2.post-title {
margin: 0;
}
body.single h2.post-title {
margin: 3em 0 1em 0;
}
Terribly useful, isn’t it? Similarly, classes could be made of categories and then applied to specific posts. For example, I have a post under the category “Foo Bar.”
When the post is run through the loop its parent div gets classes made from each category slug:
<div id="post-42" class="post foo-bar">
Let’s say I want to add a background color to the titles of all posts in the “Foo Bar” category. And I want this background color to appear only on post titles in that category if they are being shown on the home page. The CSS might be:
body.home div.foo-bar h2.post-title {
background: #C30;
}
Perhaps you’ll agree that (a) this is semantic, and (b) would be useful for theme designers and users. It could be used with CSS generally (like in the first example) or for something very specific (like in the second). The theme files are more intuitive for everyone, ergo more useful.
Adding the functionality
Note. This is clearly not the best way to create these functions, but you get the idea. To see a really elegant implementation of this, check out the functions.php of the Sandbox.
The easiest way to add this functionality to a theme is by first adding some code to a theme’s functions.php file (or in the header.php), and then adding a few PHP functions to the theme files.
An excerpt of this code for adding .home to the body might be:
function body_class() {
if ( is_home() ) {
echo 'home';
}
}
This creates a new function, body_class(), that I would add to the body element in the header.php theme file:
<body class="<?php body_class(); ?>">
I created a basic—crude, actually—function for creating classes from category slugs. This would also be best placed in the functions.php file:
function post_category_class() {
foreach ( ( get_the_category() ) as $cat ) {
echo $cat->category_nicename;
}
}
Another function is created, post_category_class(), that I will add to the div that wraps the post. And I’ll do this in all the appropriate files, e.g., index.php, single.php.
<div id="post-<?php the_ID(); ?>" class="post <?php post_category_class(); ?>">
That’s the update
I won’t claim any of this is ingenious or even original (to me—thanks, Andy) as many, many others have posted on this very topic. See Classes on the body tag and/or Dynamic ID for the <body> for just a couple examples.
This is the type of stuff I’m doing to the Minimalism Sandbox. I’m still a bit flabbergasted that this theme has generated more interest than any of my other themes, though it’s of an entirely different nature.
I’m planning on releasing another beta of it, version 0.5, by the end of the weekend. Should be a big step forward in its usefulness.
16 Comments
ok, it took me 4 reads of this to actually understand it. (and see some point in it)
that’s pretty cool. for starters, you could style asides and noteworthy posts, without going to all the trouble that fauna does.
thus far, you’re on track to replace k2 for the most optionable theme ever.
although i’m still unlcear on how semantically invalid selectors for layout items come into play. if your narrowcolumn is called
#odalisque, what does it really matter? sure, posts, widgets, comments, and every other instantiated item should have a unique id and selector, but the big layout boxes…. i’m failing to see their relevanceI don’t know that using
.narrowcolumnor even#fatdog-baconis wrong, per se. Hell, look at all my themes. As long as they validate, it’s really fine.But will you agree that
body.single h2.post-title { font-size: 10em; }makes more sense to the end user (and as a reference for the designer) than with
.narrowcolumn.I’m not sure about this, but I think that giving the main layout
div’s names (or ids) specific to what they do is semantic, likediv#wrapper.For me the benefit is being able to adjust the way, let’s say, the big box
div#contentwill appear when showing a single post page vs. a date-based archive page.just implemented, and i’m happy.
sooooo much simpler than #thebox and #box2
Yeah, great isn’t it? I see on your blog you added the semantic classes to the
bodytag, but not the posts. I’m interested why, not because I think you should or shouldn’t, but beacuse I’d like to know more about whether or not you’d find this useful. Curious only.i don’t have a div that wraps the title and the body. since the only formatting i use in posts are bold and italics, it’s not important.
and i have hardcoded asides in the squible loops.
but i’ll definately use it for the competition.
I’ll have to play with this, I see several possibilities opening up
Thanks. Bookmarked your page.
As for semantic classes and ids names… Yeah, in terms of validation, it doesn’t make one iota of difference. in terms of usefulness for yourself, it does.
Imagine you have a layout with three divs, the first div for your content, the second that you float on the left for your left column, and the third that you float right for your right column. If you call them “content”, “leftcol” and “rightcol”, and 6 months later decide to change your layout, you could, in effect, simply change the stylesheet. But what if your div that is named “leftcol” suddenly goes to the right, and the one that was “rightcol” becomes the footer? It just doesn’t make sense anymore…
hence, it makes more sense to name your divs by what they contain than where they are.
My 2 devaluated kiwi cents
Thanks, Nic.
Agreed on the semantic names for
div’s re: their purpose. Is someone brave enough to tell the ALA folks now?Hey Scott!
I suspect the ALA folks are using that to demonstrate and make it easier for Joe Q Public reading the suggested snippets to follow what is going on, rather than expecting to see the actual “left” “right” used in a real life situation.
Yet I can see where that would cause problem as so many people just cut/paste.
BTW, as an aside, this “live preview” of comments is a PITA, it just slooooows things so much.
I’m just saying the ALA people are far too clever for their own good. Well-written articles, clear presentation, and their damned easy-to-implement suggestions. Curses!
I actually need to mess with scripts on this site. I was inspired by Adam. Now I just need a couple hour to actually do it.
heh, sorry my post is so awkwardly worded and genererally un-fleshed-out. it’s actually not a complicated process.
it’s surprising that the JS for the tagsearch loads on every page, considering that it’s only useful on the tagsearch page, for which she provides sample code anyway.
Hi! Ever since I started using WordPress, I’ve been looking for a theme similar to this, and am greatly encouraged by your musings here about semantic styling - looking forward to the update. Thank you!
The Minimalist Sandbox revision is very, very close to being released. It’s still so simple, and yet very powerful.
And thanks to Andy, it (a) works and (b) is masterfully coded.
Update: The method described here for adding a dynamic, class-generating function to your WordPress blog is bit crude, really.
Look at the functions.php of the Sandbox theme for a much more elegant and thorough method. (All thanks to Andy.)
Scott,
Thanks for your comment on my ClassyBody plugin page.
I would seriously suggest you consider using it with Sandbox. I plan to build off Sandbox for a theme I am thinking about for my site, and I definitely will be using ClassyBody.
Note also that I have updated it now to include custom classes via WP Custom Fields (for posts or pages).
All the best
- Alister
Hi Alister: I think the Sandbox body, post, and comment classes work quite well as they are. Tremendously powerful. And quite a number of themes are using the Sandbox dynamic classes (as well as the hAtom microformat) by default, such as K2.
Good idea about the custom field for the post or page. I’ll be interested to see that in action.
Can this be added easy enough to the veryplaintxt theme?
I want to implement the Pure CSS Asides that Andy Skelton started a thread on over at WordPress forums.