By epersonae

2011-03-02 23:46:10 8 Comments

I'm cleaning up my big crazy style sheets (possibly pertinent to a future question) and I'm wondering the best way to add custom CSS to a specific node or page.

In particular, my work site's home page is a Panel Page and it has a bunch of different styling. Right now the CSS is just included with the main theme style sheet.

Is there a way to say, "if this is node Foo, then add foo.css"? Is CSS Injector what I'm looking for?

I might be interested in generalizing this to other nodes/sections/etc, but at the moment I just want to handle this one item.

What I ended up doing.

I'm using a Zen subtheme, and discovered in actually reading through template.php that there's some commented out code for including conditional style sheets. Code below did exactly what I needed:

if (drupal_is_front_page()) {
  drupal_add_css(path_to_theme() . "/foo.css", 'theme','all'); 

(Line 80 in a stock Zen template.php file, FWIW.)


@Markus Zerres 2018-01-13 17:32:15

You can print the page node in the body-tag

<body page-node-26419 ...>

Then you can restrict {
    background: red

This is useful for minor quick changes

@Kojo 2018-01-13 17:58:00

welcome to Drupal Answers ! This answer has already been provided above by Dave Reid.

@budda 2011-03-03 00:43:21

Create a Context for your page/section and then use the Context Assets module to load CSS and/or javascript for that given context.


Context allows you to manage contextual conditions and reactions for different portions of your site. You can think of each context as representing a "section" of your site. For each context, you can choose the conditions that trigger this context to be active and choose different aspects of Drupal that should react to this active context.

Think of conditions as a set of rules that are checked during page load to see what context is active. Any reactions that are associated with active contexts are then fired.

Context Add Assets:

Context add assets allows you to do this. It has an easy to use UI to allow you to do this all without writing any code. Because it uses ctools all of this is also exportable.

@electblake 2011-03-16 21:03:56

I use Context Add Assets in literally every website I make - if your into Context's (which drive every section of my builds) Add Assets is perfect!

@Paul Jones 2011-03-03 00:03:46

For an admin based way of doing it I'd look at the CSS module. It adds a field where you can add CSS to the node/add and node/edit pages.


The CSS module adds, for users with enough permissions and enabled nodes, a CSS field on the node creation page.

Users might insert CSS rules in the CSS node field and those rules will be parsed on the node viewing.

This way CSS experienced users might create complex CSS based design for nodes contents.

Important: note that the CSS editing permissions should be given only to trusted users (administrators). Malicious users which have this permission might broke your site design and also introduce security issues (XSS).

@Decipher 2011-03-02 23:53:13

This is the sort of thing that I'd do by code, but that's because that's just the way I roll.

In the template.php you will want something like:

function MYTHEME_preprocess_node($vars) {
  if (drupal_get_path_alias("node/{$vars['#node']->nid}") == 'foo') {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/css/foo.css");

Replace foo with values related to your own code.

@epersonae 2011-03-02 23:59:27

so for the home page, would you use if(drupal_is_front_page()) { instead of if(drupal_get_path_alias [etc]?

@Decipher 2011-03-03 00:06:06

Yes, the conditions are entirely up to you. You could simply do a $vars['#node']->nid == $nid check if you wanted.

@medden 2012-06-28 07:23:10

Decipher, can't find any fault with your code. But hope you don't mind me pointing out that unless you are talking about Drupal permission configuration, the way you role should actually be the way you roll. ;-)

@Wes Johnson 2014-02-14 21:50:57

FYI, I'm using Drupal 7 and found that I needed to use $vars['elements']['#node']->nid instead in the alias lookup. There's no #node root in vars in the latest Drupal 7 from the looks of it.

@pal4life 2014-06-05 22:57:33

shouldn't it have function ahead of MYTHEME__preprocess_node($vars) I see all the code in there just being in terms of functions?

@pal4life 2014-06-05 23:26:22

I am getting an error here Undefined index: #node in mytheme_preprocess_node()

@pal4life 2014-06-09 22:06:14

This was a little misleading answer for Drupal 7. What helped me was if ($vars['elements']['#node']->title == 'Title of Node') or you can do this with node id if ($vars['elements']['#node']->id == 'Substitute Node Id here'). But Since my nodeids change from my dev to Staging so going with title in this case

@jphelan 2017-05-04 21:43:07

Should be $vars['node']->nid instead of $vars['#node']->nid

@mixerowsky 2014-08-13 14:48:35

Try to add this in your 'template.php' file:

function mytheme_preprocess_page (&$variables)
  if (drupal_is_front_page()) {
    drupal_add_css(drupal_get_path('theme','mytheme'). '/css/front.css');

Replace 'mytheme' with name of your theme directory and '/css/front.css' with path where is your CSS file.

To unset 'front.css' file from other pages try to add to 'template.php':

function hook_css_alter(&$css) {
  if (!drupal_is_front_page()) {
    unset($css[drupal_get_path('theme', 'mytheme') . '/css/front.css']);

Again, replace 'mytheme' with name of your theme directory.

If you need to unset 'styles.css' from front page just combine these two codes.

Lets assume that you need 'front.css' without 'styles.css' on front page, and 'style.css' without 'front.css' on all other pages. Code will look something like this:

function mytheme_preprocess_page (&$variables)
  if (drupal_is_front_page()) {
    drupal_add_css(drupal_get_path('theme','mytheme'). '/css/front.css');
  else {
    drupal_add_css(drupal_get_path('theme','mytheme'). '/css/styles.css');

function hook_css_alter(&$css) {
  if (drupal_is_front_page()) {
    unset($css[drupal_get_path('theme', 'mytheme') . '/css/styles.css']);
  else {
    unset($css[drupal_get_path('theme', 'mytheme') . '/css/front.css']);

Also, replace 'mytheme'.

I hope this will be helpful.

@Sd1 2014-08-13 17:29:07

The last piece of code is what I needed. And it works, i.e., after I removed stylesheets[all][] = css/front.css from my - I guess I assumed wrongly that we need to have that along with stylesheets[all][] = css/styles.css. I was also worried that because I'm overriding page.tpl.php with page--front.tpl.php it might not work but everything seems to be holding up nicely. This is truly helpful. Thanks!

@Sd1 2014-08-14 17:42:55

Just to make sure everybody gets this solution; make sure to remove styles.css (the default) and front.css from your file. Flush all caches and it should be good to go.

@augusto 2013-11-22 11:41:18

Aside the Drupal approach, when you only need a short piece of css inside your HTML5 body, you have the css scoped Attribute. See

This solution will save you from editing code and installing more modules

@Druvision 2012-12-25 21:45:24

CodePerNode is great, but CSS Injector is simpler to install (no libraries needed). The module allows the content manager to dynamically add CSS to specific pages, without touching PHP code or INFO files at all. 15777 installs can't be wrong - this is a social proof this module works. The CSS is also cached with the regular caching system.

@Alexander Hripak 2012-11-02 20:28:36

I would've skipped touching template.php altogether and just add another item in your theme's .info file

Say your stylesheet is in css/foo.css.

This is how your file would look:

name = Theme Name
stylesheets[all][] = css/foo.css

Then you benefit from having it cached with the main stylesheets, and since I'm assuming this is for your homepage it would make sense.

@Alexander Hripak 2012-11-02 20:30:06

And of course you would need to qualify your selectors based on the node's attributes, i.e. nid, node type, etc

@pal4life 2014-06-06 15:03:49

The problem with this approach is it will affect all the pages on the site with the css added here

@tal 2012-09-12 18:30:43

/* An example using bartik theme to add css based on content type */

function bartik_preprocess_node(&$variables) {
if(!empty($variables['node'])) {
    if($variables['node']->type == 'my_custom_content_type')
      drupal_add_css(drupal_get_path('theme', 'any_theme_name') . "/css/foo.css");   
  // Some other code here

@Warpstone 2012-09-12 14:39:09

Since you're already using Panels, it might be easier to to just add your CSS as a Panel Style for each region of your homepage panel. You can define custom markup there and reuse it across your site.

You can also just go to the General section of the page manager variant rule for your homepage. There is a section here for adding CSS IDs and rules for only the current panel.

Note: this is all in D7, so it might be that this approach is better supported by Panels than it was in prior versions.

@kiamlaluno 2011-06-06 00:35:06

If the criteria for which adding a CSS style depends from some properties of a node, then I would implement MYTHEME_preprocess_node(&$variables); one of the values passed to the function is $variables['node'] (to notice it's not $variables['#node']).

MYTHEME_preprocess_node(&$variables) {
  if ($variables['node']->nid == 3) {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/foo.css");

If the criteria don't depend from any node properties, then I would implement MYTHEME_preprocess_page(&$variables); $variables['node'] contains a node object, if the page being shown is a node page. In Drupal 6, the process function also gets $variables['is_front'], but in Drupal 7 the same variable is not passed; if you need to know if the page is the front page, you need to use drupal_is_front_page().

MYTHEME_preprocess_page(&$variables) {
  if ($variables['is_front']) {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/foo.css");

@rakke 2011-05-30 15:59:30

You could have a look at the Code per Node module. It is also featured in this blog post.

@Camsoft 2011-03-03 00:12:54

You could create a custom module and use hook_preprocess_node() to load stylesheets selectively based on the node id.

Here's an example:

function MYMODULE_preprocess_node($vars) {
  $nid = 3;
  if (arg(0) == 'node' && is_numeric(arg(1)) && arg(1) == $nid) {
    drupal_add_css(drupal_get_path('theme', 'MYTHEME') . "/foo.css");

Replace MYMODULE with the name of your module and replace MYTHEME with the name of the theme that contains the css file.

@Decipher 2011-03-03 00:15:06

hook_init() runs on every page load, and often multiple times (AHAH), why not use hook_preprocess_node() (either in the theme or in a module) which only runs when a node is rendered?

@Camsoft 2011-03-03 00:19:29

Good point, did not know that init was loaded multiple times.

@Camsoft 2011-03-03 00:27:27

Decipher, I've corrected my example to use the preprocess function. Still learning!

@Decipher 2011-03-03 00:30:22

Then the next question would be why use arg(1) for the nid when the node variables are passed through $vars :) Which would then lead to the next question of how is this different to my answer :p

@Camsoft 2011-03-03 00:32:29

I guess I should have read the hook_preprocess_node() documentation. You're absolutely right. epersonae, I suggest you accept Decipher's answer.

@Danny Englander 2013-06-12 15:50:44

This is ok but not ideal for exportable code where the nid might be different on a production or remote environment. It would be better to do an alias pattern match (as answered above) which would most likely be the same in all environments.

@Dave Reid 2011-03-03 00:13:55

If it's a small amount of CSS, maybe considering making your CSS selectors based on the node and including the css in your theme's CSS? Drupal 7 provides the selector, and Zen for Drupal 6 provides similar body CSS classes.

@epersonae 2011-03-03 00:27:06

that's basically what I was doing...and it's almost 200 lines, so it seemed like a good idea to move it elsewhere. (yes, it should probably be shorter. that may be a separate step.)

@epersonae 2011-03-03 00:28:37

On the other hand, your response inspired me to read the template.php in my (Zen child) template, which got me to the final answer.

Related Questions

Sponsored Content

1 Answered Questions

Any way to add CSS for common path?

  • 2018-05-12 00:02:22
  • cfranco
  • 26 View
  • 0 Score
  • 1 Answer
  • Tags:   theming hooks

1 Answered Questions

styling submit form button for mobile

  • 2015-09-02 15:37:12
  • Anon Ymous
  • 800 View
  • -1 Score
  • 1 Answer
  • Tags:   forms theming

1 Answered Questions

[SOLVED] Zen theme doesn't append content titles to breadcrumbs

2 Answered Questions

[SOLVED] Problems getting Carousel jQuery plugin working

  • 2015-12-19 10:27:02
  • Bruno Vincent
  • 814 View
  • 0 Score
  • 2 Answer
  • Tags:   7 javascript

2 Answered Questions

[SOLVED] Allow CSS styling in node filtered HTML view?

  • 2012-10-01 20:32:12
  • Paul S.
  • 1602 View
  • 5 Score
  • 2 Answer
  • Tags:   7 theming

1 Answered Questions

[SOLVED] How to Style in Drupal

  • 2015-01-08 03:45:48
  • Sage
  • 139 View
  • 0 Score
  • 1 Answer
  • Tags:   theming

1 Answered Questions

Different styling for each teaser display

1 Answered Questions

[SOLVED] Zen sub theme: page--node--name.tpl.php not working!

  • 2013-07-28 17:04:44
  • everaftergraphics
  • 2257 View
  • 0 Score
  • 1 Answer
  • Tags:   theming

1 Answered Questions

[SOLVED] Tao overriding parent reset.css file.

  • 2011-07-26 13:33:20
  • Rod
  • 574 View
  • 0 Score
  • 1 Answer
  • Tags:   6 theming

3 Answered Questions

[SOLVED] How do I display bare, stripped content with no menus, footers, etc?

  • 2011-06-17 18:23:31
  • Wannabe Tycoon
  • 3559 View
  • 2 Score
  • 3 Answer
  • Tags:   theming

Sponsored Content