Community Documentation

Adding styles through the API

Last updated August 12, 2011. Created by LeeHunter on February 23, 2008.
Edited by rayvan, Tor Arne Thune, kiamlaluno, jhodgdon. Log in to edit this page.

Adding styles through the .info file should be sufficient for most themes. Since the .info file is static, style sheets cannot be added dynamically. Depending on how the theme handles style sheets, it may not matter altogether. When in doubt, use the .info file.

There are two API functions for working with style sheets, drupal_add_css and drupal_get_css. Here is an example to dynamically add styles sheets.

Change the "drop" prefix to the name of your theme.

<?php
function drop_preprocess_page(&$variables) {
 
$front_style = path_to_theme() .'/front-page.css';
 
$path_style = path_to_theme() .'/path-'. arg(0) .'.css';

  if (
file_exists($front_style) && $variables['is_front']) {
   
$include_style = $front_style;
  }
  elseif (
file_exists($path_style)) {
   
$include_style = $path_style;
  }

  if (isset(
$include_style)) {
   
drupal_add_css($include_style, 'theme', 'all', FALSE);
   
$vars['styles'] = drupal_get_css();
  }
}
?>

The above example would include the style sheet "front-page.css" on the front page or many others based on the internal path. For example, http://example.com/admin would pickup on "path-admin.css".

A few notes:

  • Depending on where and when the style is added, drupal_get_css may need to be called in order to include the added styles. They are initially retrieved in template_preprocess_page. See Preprocessors and variables for details on the order of the preprocessors.
  • There is a parameter in drupal_add_css to aggregate the added file. Consider disabling it like the above example when the inclusion of the style sheet is very dynamic, since files added to the larger aggregate will force a new aggregated CSS file to be recreated. In effect, it can slow down the retrieval of the page and consume more bandwidth.

Where To Add Code

This code can be added in the template.php file in your theme directory.
There may already be a function there called "phptemplate_preprocess_page".
Just include it within the body of your XXX__preprocess_page function.

You may also need to change "variables" to "vars" to make it work.

Comments

drupal_add_css troubleshooting

Users should be careful with how they define their variables, in their implementation of the above example. For some reason (maybe a security issue with drupal, or with certain hosting services, I don't know), using 'path_to_theme()' and 'arg(whatever)' in the same line poses problems. Define a separate 'static' variable one step earlier, and use THAT in the same line as 'path_to_theme()'.

For example, THIS didn't work, in my case:

$name_segment = arg(0)."-".arg(1);
$path_style = path_to_theme() .'/mytheme-'.arg(0).'-'.arg(1).'.css';

but THIS DOES:

$name_segment = arg(0)."-".arg(1);
$path_style = path_to_theme() .'/mytheme-'.$name_segment.'.css';

You then must be sure to have style sheets mytheme-node-number.css available, but that's the easy part.

css not added

Using drupal_add_css() does not add the style sheet when called in hook_preprocess_page, so i putted it at the begin of the template.php ...

Preprocess page doesn't work for me.

Here's the code in my template.php file:

/* preprocess for pages, checking for home page */
function hope_globaltheme_preprocess_page(&$variables) {

// if front page, add home stylesheet
if ($variables['is_front']) {
drupal_add_css($variables['themepath'] . '/css/index.css','theme','all',false);
}

$variables['styles'] = drupal_get_css();

}

Where the name of my theme is "hope_globaltheme". I know the "if" conditional is working because I can put a print statement in there and it will show up. I set 'themepath' variable in the preprocess function for my theme, so that variable is also known. I also tried with a full, hard-coded path to the CSS.

The indicator I get that this isn't working is that the CSS doesn't show up in the HEAD tag of my home page. And yes, I could add it in the .tpl file but I'm trying to do this the correct Drupal way using preprocess functions. I've seen other places that have said the preprocess_page function is too late to add CSS in. So now I'n not quite sure where I need to add this.

I'm using Drupal core 6.20 (haven't moved to 7 yet)

Use $vars['styles'] instead

Use $vars['styles'] instead of $variables['styles']

That's what made it work for me...I was hitting my head on a wall til I made it work with this.

The code that works

It seems that sometimes the drupal_add_css doesn't work as expected even though all the right steps are followed.

If this is the case then simply try this:

<?php
$inc_path
= drupal_get_path('theme', 'your-theme-name') . '/my-styles.css';
$file = realpath(".") ."/". $inc_path;
if(
file_exists($file)) {
  
drupal_add_css($inc_path , 'theme', 'all', FALSE);
  
$vars['css']['all']['theme'][$inc_path] = 1; // this is what makes it work!
  
$vars['styles'] = drupal_get_css();       
}
?>

you might have to change bits and bobs, but it's clear now :)

KieLa.

d7 - changing css files dynamically

This probably isn't the best thread, but not sure where else to put this. I am using the jquery ui datepicker inline as the core of a publicly-available calendar page in my site. Drupal 7 comes packaged with two css files ('sites/all/modules/date/date_popup/themes/datepicker.1.7.css' and 'misc/ui/jquery.ui.theme.css') that affect the appearance of the popup calendar when adding/editing date content. These default styles were totally ruining my inline calendar.

So, I wanted to dynamically unset those two stylesheets. There's lots of documentation online for this in d6, but I couldn't find anything for d7. I've found something that worked for me - grab all stylesheets with drupal_add_css, then unset the problem files, reset all css files to clear everything, then dynamically load all of the files except for the problem files with drupal_add_css. This seems really wasteful, but it works. If anyone has a better suggestion on how to accomplish this...

In template.php, THEMENAME_preprocess_page function:

if ($vars['node']->type == 'calendar'){
  $stylesheets = drupal_add_css();
  unset($stylesheets['sites/all/modules/date/date_popup/themes/datepicker.1.7.css']);
  unset($stylesheets['misc/ui/jquery.ui.theme.css']);
  drupal_static_reset('drupal_add_css');
  foreach ($stylesheets as $k){
    drupal_add_css($k['data']);
  }
}

use hook_library_alter

Hi,
this works for me:

function THEMENAME_library_alter(&$libraries, $module) {
    unset($libraries['ui']['css']['misc/ui/jquery.ui.theme.css']);
}

use hook_css_alter

<?php
function THEMENAME_css_alter(&$css) {
 
$exclude = array(
   
'sites/all/modules/date/date_popup/themes/datepicker.1.7.css' => FALSE,
   
'misc/ui/jquery.ui.theme.css' => FALSE,
  );
 
$css = array_diff_key($css, $exclude);
}
?>

Remote css / stylesheets

If your looking for a way to link to remote style sheets you should check out http://drupal.org/node/905994#comment-4858642

It doesn't appear that this

It doesn't appear that this code works in D6, at least in the preprocess_page. Drupal_add_css doesn't seem to change $variables['css']. Here's the code that worked for us:

function phptemplate_preprocess_page(&$vars) {

$vars['template_files'][] = "page-type-college_links_homepage";
$inc_path = drupal_get_path('theme', 'inroads') .'/bootstrap.min.css';
   $vars['css'] = drupal_add_css($inc_path , 'theme', 'all', TRUE);
   unset($vars['css']['all']['theme'][drupal_get_path('theme', 'inroads') .'/style.css']);
   $vars['styles'] = drupal_get_css($vars['css']); 

. . .

drupal_add_css returns the css array, but doesn't actually change $vars['css']. So too, drupal_get_css doesn't grab $vars['css'], but grabs instead the static or global $css variable. Perhaps you have to declare $vars['css'] as the static $css. Don't know. But the code above worked for me.