Styling Individual Posts Based On Category

One of the reasons I like to help out in the WordPress Support Forum is it gives me yet something else to blog about. A recent poster asked if it was possible to apply a different style to categories. The answer is yes.

Back on 09 April 2008 I showed you how to create a page with a unique style. (see Create Pages With a Different Style Sheet) To summarize that post you only need to create a new style sheet, upload it to your theme’s folder, then call that style sheet in header.php. In that post we used is_page() but you can easily substitute is_category().

Let’s assume you have a category called “news” that you want to apply a different style to. Using your theme’s style sheet as a guide, create a new one, call it something like news.css and upload it to your theme’s folder. I chose the name news.css purely for the sake of organization but you can call it anything you want. Next, look in header.php for the call to the regular style sheet. It will look something like this …

<link rel="stylesheet" href="<php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

We then wrap a few lines of code around that as such …

<?php if ( is_category('X') ) { ?>
<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />
<?php } else { ?>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>"  type="text/css" media="screen" />
<?php } ?>

… where X is the numerical ID of the category you want to style. What that says is if we are on the category page with the numerical ID of X use news.css and if not then use style.css.

Now this is fine for styling category pages, that is, the pages that contain a list of posts from a certain category. However if you click on one of the post titles to read that particular entry your special styling will be lost. Why? Because we are now using a different page template. According to the WordPress template hierarchy individual posts are displayed using single.php. Can we style those pages as well? Again the answer is yes.

Let’s assume you have completed the above and have your special styling applied to the “news” category page. We now want to apply that same styling to all of the individual posts from that same category. First, make 2 copies of single.php and call them single-a.php and single-b.php. You will now have 3 php files for displaying individual posts – single.php, single-a.php and single-b.php. Open single.php and delete the contents. Now insert the following …

<?php
$post = $wp_query->post;
if ( in_category('X') ) {
include(TEMPLATEPATH . '/single-b.php');
} else {
include(TEMPLATEPATH . '/single-a.php');
}
?>

Again, X being the numerical ID of the category you want to style. What the above says is if we are on the single post page that belongs to category X use the template file single-b.php and if not use single-a.php. So far so good. Now the rest gets a little tricky but it’s not that difficult. Just take your time and reread everything as many times as you need to.

So far we have created 2 new php files for displaying individual posts and have altered the original single.php file so that it now is simply a conditional file telling WordPress which template file to use under certain conditions. We also have the style sheet – news.css – you created earlier. Since style sheets are called in header.php we need to create a new header.php file. Make a copy of your theme’s header.php file and call it newsheader.php (once again I chose the name merely for the sake of organization) Open up newsheader.php and look for the call to the style sheet. It will look something like …

<link rel="stylesheet" href="<php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

Replace it with this …

<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />

Or, if you have already made the modifications to header.php that I mentioned earlier your newsheader.php will probably contain the following since it is an exact copy of header.php …

<?php if ( is_category('X') ) { ?>
<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />
<?php } else { ?>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>"  type="text/css" media="screen" />
<?php } ?>

If newsheader.php contains the above simply delete it and again replace it with this …

<link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/news.css" type="text/css" media="screen" />

Now we go to single-b.php and at the top you will see <?php get_header(); ?> Replace that with <?php include ('newsheader.php'); ?>

What we have done is tell WordPress if we are on a single post page belonging to category X use single-b.php which contains a call to newsheader.php which in turn contains a call to news.css and if not use single-a.php

About Len Kutchma

Len has been blogging for over 10 years and is a rabid WordPress fan. In addition to blogging here you can find him writing the occasional article and toiling away in the forums at WeblogToolsCollection.com. He also hangs out at the WordPress support forums lending a hand when he can. You can also find him at Google+ Twitter and GitHub.

Comments

  1. This would be perfect if I could use a category name rather than

    the numerical ID of the category you want to style

    If it is possible could you please email me a solution i would really appreciate that!

  2. Sorry, scrap that! I decided to try it anyway using a category name and it works just fine! Thanks for that.

  3. You’re welcome Ryan.

  4. Is there anyway you could adapt this, to display a different author.php, based on the author ID?

    cheers
    adam

    • That’s a very good question Adam. Hmmm, I’d have to think about that. Off the top of my head I would think you’d first need to get the author ID then somehow use the template tag the_author_meta

      More reading on that particular template tag.

  5. really fantastic, just what I was looking congratulations !!!!!!

  6. Horacsio says:

    Hi Len,
    thank you for all your kind willing to help with this blog ;)
    I would like to know if it’s possible, instead of different styles, to create diferent post apearances. I mean for the news which is the opening blog cat. I want to make appear the post title, the post content and the date, but for other all categories I only want the title and the post content.
    I wonder if you could point any solution out there.
    Thank you ;)

    • Len Kutchma says:

      Hi Horacsio

      If you’re using individual category template files for each of the categories you could simply omit the bit that calls the post meta info. I can’t be more specific as it’s done slightly differently from theme to theme.

  7. Thanks for this. It’s great.

    Is it possible to show different styling in the home page for posts with different categories?

    In the homepage, we often list and display posts with excerpts under different categories. So how can I show different css styling?

    I’ve tried your solution above and it works but this only applies to pages and templates but it didn’t reflect in individual posts with excerpts under different catefories on the homepage.

    Appreciate it if you can show us how so that it will beneift the rest. Thanks!

    • Len Kutchma says:

      Hi Yahya

      Your Gravatar looks familiar. I’m sure I’ve seen you somewhere in the WordPress community before. :)

      I haven’t had the time to test anything (I’m a roofer and currently swamped with work) but you could try playing around with is_home or is_front and try to set styles that way.

      • Len Kutchma says:

        Also, WordPress now dynamically generates body classes. (this post was written a couple of years ago) You can take advantage of those body classes by targeting them in the style sheet.

        For example, let’s say you have a category called General. In style.css you could play around with something like this …

        .category-general .entry {
        YOUR STYLE RULES HERE
        }

  8. AWESOME POST!!

    Just what I was looking for, and took hours of searching tooo =P

    Used the “css-javascript-toolbox” plugin, but only does categories and didn’t feel like pasting every single url that needed different css…

    You rock, Len

    Thank you!!

    Mike

What Do You Think?

*

Please read the Comment Policy before submitting a comment.