Drupal 6 Theming: Adding and Optimizing CSS Files


Drupal 6 Theming Cookbook

Drupal 6 Theming Cookbook

Over 100 clear step-by-step recipes to create powerful, great-looking Drupal themes

  • Take control of the look and feel of your Drupal website
  • Tips and tricks to get the most out of Drupal's theming system
  • Learn how to customize existing themes and create unique themes from scratch
  • Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible
        Read more about this book      

(For more resources on Drupal, see here.)

Including a CSS file in a theme

This recipe details the steps involved in adding a CSS file to the theme via its .info file. In this case, we will be adding a CSS file to the mytheme sub-theme which we created in the previous article.

Getting ready

Create a CSS file inside the theme's folder named mytheme.css and add the following example rule to it:

* {
color: #996633 !important;

This rule should override and change the color of all text on the page to a brownish hue.

How to do it...

Adding a CSS file to a theme is best accomplished via its .info file. Navigate to the theme's folder at sites/all/themes/mytheme and open the mytheme.info file in an editor. Add the following line to this file to include our CSS:

stylesheets[all][] = mytheme.css

If the CSS file is stored along with other stylesheets in a sub-folder named css, the syntax would include the relative path to the file as follows: stylesheets[all][] = css/mytheme.css.

Once done, save the file and exit the editor. Since we have modified the .info file and introduced a new file, our changes will not take effect until the theme registry is rebuilt. Therefore, clear the Drupal cache and view the site to confirm that our new stylesheet has been included correctly. The theme should now display all text in brown.

How it works...

Drupal checks the .info file and notes that we have declared stylesheets using the stylesheets variable. The syntax of this variable is similar to that of an array in PHP. The all index in the syntax represents the media type as used in CSS declarations.

The next screenshot displays a section of the source code of a page which confirms the inclusion of the new stylesheet, mytheme.css. We can also see that our sub-theme is including the stylesheets declared by its base theme—Garland—as well as its own stylesheets.

In the preceding screenshot, we can see that Drupal references each stylesheet along with a query string. For example, mytheme.css is included as mytheme.css?e. This rather quirky suffix is a trick used by Drupal to ensure that browsers do not use stale copies of a cached CSS file while rendering our site.
We can test this by clearing the Drupal cache and viewing the source code once again. Now, our stylesheets should have a different suffix— perhaps, something like mytheme.css?A—thereby tricking browsers into believing that these are different files and using them instead of their cached copies.

There's more...

One of the advantages of using a sub-theme is that we can easily override elements of the base theme. This includes stylesheets as well.

Overriding the base theme's stylesheet

If the base theme includes a stylesheet named layout.css, adding a stylesheet of the same name in the sub-theme will override the base theme's stylesheet. In other words, Drupal will include the sub-theme's stylesheet instead of that of the base theme.

Enabling CSS optimization

CSS optimization in Drupal is accomplished through two steps—aggregation and compression. This optimization provides a significant boost to performance both on the server as well as for the user. This recipe details the steps to be performed to enable this feature in Drupal.

Getting ready

CSS optimization is a requirement only when a site is ready to go live. Until such time, it is recommended that it be left switched off as CSS changes during development will not take effect unless the Drupal cache is cleared.

How to do it...

Optimization and other performance-related features are sequestered within admin/ settings/performance (Home | Administer | Site configuration | Performance). This performance configuration page should have a section titled Bandwidth optimizations which should contain options for CSS and Javascript optimization. Look for the setting named Optimize CSS files and set it to Enabled as in the following screenshot:

Public File system
As the screenshot states, the optimized CSS file is cached using Drupal's file system which needs to be set to public to ensure that the user's browser can access and download it. Therefore, it is necessary to set Download method of the Drupal file system to Public. This can be done via admin/settings/file-system (Home | Administer | Site configuration | File system).

Once done, click on the Save configuration button at the bottom of the page to save our changes.

How it works...

Aggregation involves the collating and joining of multiple CSS files into a single stylesheet, while compression reduces the resulting file to a smaller size by trimming out unnecessary elements such as whitespace. The former helps in reducing the number of files that the server has to load and serve. The latter saves on bandwidth and time.

The previous and following screenshots demonstrate CSS optimization at work. The previous screenshot is a snippet of the HTML source of a Drupal page running on a stock Garland theme. As displayed, this involves the server performing look-ups and serving eight separate CSS files—seven for all media types and a print stylesheet—for each and every page served. If this is extrapolated to sites of greater complexity, the number of files and, consequently, the server and bandwidth load, begin to take on significant proportions and can seriously impact performance.

The preceding screenshot is of the same page as before with one difference—CSS optimization is now turned on. The number of CSS files has now been reduced to only two—one for all media types and the other being the print media type. These stylesheets are stored in the files folder and are cached copies. As a result, each page load now only involves the webserver serving two files instead of the previous eight.

There's more...

CSS optimization and other performance improvements should be used with care.

When to use it

CSS optimization is only necessary to improve performance on production sites. Enabling it beforehand will only hinder theme development.

Enabling optimization can sometimes be handy when working on sites which are using more than 31 stylesheets—a not too infrequent occurrence on sites using a plethora of modules and an elaborate theme—as this is an upper-bound for Internet Explorer. IE will only load the first 31 stylesheets and ignore the rest. Drupal's CSS optimization feature reduces this number to one, thereby conveniently working around the issue. An alternative is to use modules such as IE CSS Optimizer (http://drupal.org/project/ie_css_optimizer).

Other optimizations

Other optimization settings can also be configured on the performance page. These include page caching, block caching, and JavaScript optimization. It is also worthwhile browsing the caching and performance modules that are available as contributed modules via http:// drupal.org/project/modules under the category Performance and scalability.

Creating the mysite module to hold our tweaks

In the course of developing our site, we will frequently come across situations where various elements of the site need to be tweaked in PHP using Drupal's APIs. While a lot of theme-specific cases can be stored in template files, certain tweaks which are theme-agnostic require that we store them in a module to ensure that they are available to all themes.

This recipe covers the creation of a module to hold all these bits and pieces.

Getting ready

Create a folder inside sites/all named modules. This is where custom and contributed modules are usually housed.

How to do it...

The following list details the procedure involved in creating a module named mysite to hold our theme-agnostic customizations and other odds and ends:

  1. Create a folder inside sites/all/modules named mysite where mysite refers to the name of our site.
  2. Create a file named mysite.info within the mysite folder.
  3. Edit this file and add the following code inside:

    name = Mysite
    description = A module to hold odds and ends for mysite.
    core = 6.x

  4. Save the file.
  5. Create another file named mysite.module which will hold our odds and ends.
  6. Save and exit the editor.
  7. Finally, enable the module via the module administration page at admin/build/ modules (Home | Administer | Site building | Modules).

How it works...

Just as with themes, modules require a .info file which provides information to Drupal on compatibility, dependencies, and so on. Once Drupal ascertains that the module is compatible with the version installed, it loads the .module file of the same name and processes it accordingly.

We can test if the module is working by adding a snippet such as the following:


* Implementation of hook_init().
function mysite_init(){
// Display a message on every page load.
drupal_set_message("Welcome to MySite!");

As the comment suggests, the preceding snippet will display a welcome message on every page load.

There's more...

The Drupal community routinely comes up with modules to ease the pain of development.

Module builder

There's a module available named Module builder which can be used to generate a skeleton of a general module. This can subsequently be populated as per our requirements. It is available at http://drupal.org/project/module_builder.

        Read more about this book      

(For more resources on Drupal, see here.)

Adding a CSS file from a module

Situations arise where CSS files or CSS rules are to be added from a module. This recipe covers the steps required to do so.

Getting ready

We will be adding the CSS to the mysite module as created in the previous recipe. Create two CSS files named mysite.css and mysite_special.css inside the mysite module's folder and populate them with some sample rules.

How to do it...

Add the following code to the mysite module:

* Implementation of hook_init().
function mysite_init() {
// The path to the mysite module.
$path = drupal_get_path('module', 'mysite');

// Include mysite.css.
drupal_add_css($path . '/mysite.css');

// Include mysite_special.css, but do not preprocess.
drupal_add_css($path . '/mysite_special.css', 'module', 'all',

Save the file and visit the site to check if the two CSS files are now included.

How it works...

The drupal_add_css() function is used to add CSS files from a module. Its syntax is as follows:

drupal_add_css($path = NULL, $type = 'module', $media = 'all',
$preprocess = TRUE)

The documentation for this function explains each of the parameters:

  • $path denotes the path to the CSS file relative to the base_path().
  • $type indicates the type of stylesheet that is being added—a module stylesheet or a theme stylesheet with module being the default.
  • $media sets the media type for the stylesheet which can include all, print, screen, and so on.
  • Lastly, $preprocess specifies if the CSS file should be aggregated and compressed if this feature has been turned on.

In our snippet, we first get the path to the mysite module using drupal_get_path() and with the result, can obtain the complete path to mysite.css. We can now add this CSS file using drupal_add_css().

The next CSS file—mysite_special.css—is as the name suggests, a special file, that we do not want to be preprocessed. This could be because we are going to be including it conditionally, or perhaps, because we have encountered quirks in certain browsers when this file is aggregated. Consequently, we can use the following syntax to instruct Drupal to avoid preprocessing this file.

drupal_add_css($path . '/mysite_special.css', 'module', 'all', FALSE);

Looking at the source code of a typical page on the site when CSS optimization is enabled, we should see the stylesheets included similar to the following transcription:

<link rel="shortcut icon" href="/mysite/misc/favicon.ico" type="image/
x-icon" />
<link type="text/css" rel="stylesheet" media="all" href="/mysite/
sites/all/modules/mysite/mysite_special?8.css" />
<link type="text/css" rel="stylesheet" media="all" href="/mysite/
sites/default/files/css/css_32c93f4662aecdab9e9b87330ae5f157.css" />
<link type="text/css" rel="stylesheet" media="print" href="/mysite/
sites/default/files/css/css_456756789c4eab1267644ab3f147a231.css" />

As the preceding markup attests, the mysite_special.css file is never aggregated while plain old mysite.css is always aggregated.

Drupal API documentation
Drupal documentation for drupal_add_css(), drupal_get_path(), and every other function is available at http://api.drupal.org.

There's more...

Besides adding external stylesheets, the Drupal API also allows for adding inline CSS.

Adding inline CSS

Inline CSS can be added with the drupal_set_html_head() function which can insert just about anything between the HEAD tags of an HTML document.

drupal_set_html_head('<style type="text/css">body { color: #000; }</

Displaying a different theme for each day of the week

This recipe provides the PHP code that allows the rotation of themes based on the day of the week.

Getting ready

As we have seen in other recipes in this article, a number of sites use an "odds and ends" module to handle tweaks and customizations particular to the site. We will be using the mysite.module created earlier in this article to hold our customizations. It is assumed that the module is available and already enabled.

How to do it...

Open the mysite module file and paste the following code into it:

* Implementation of hook_init().
function mysite_init() {
global $custom_theme;
// An array of themes for each day of the week.
// These themes do not have to be enabled.
$themes = array();
$themes[0] = 'garland';
$themes[1] = 'minnelli';
$themes[2] = 'bluemarine';
$themes[3] = 'pushbutton';
$themes[4] = 'chameleon';
$themes[5] = 'marvin';
$themes[6] = 'mytheme';
// Get the current day of the week in numerical form.
$day = date("w");
// Override current theme based on day of the week.
$custom_theme = $themes[$day];

If the module is named something else, the function mysite_init() will need to be renamed appropriately. In case the module already contains an existing hook_init() function , the contents of the function below will need to be integrated appropriately to the end of the existing function.

Save the file and then refresh the page on the Drupal site to see this snippet at work. Due to the nature of this feature, it might be necessary to fiddle with the computer's date settings to simulate different days of the week during testing.

How it works...

The function hook_init () is run on every page without exception. It is also run before Drupal gets to the theming stage when it displays every page. Consequently, this is the best place to override the theme to use.

We are overriding the site's theme by manipulating a global variable named $custom_theme. If it is set, then Drupal changes the theme being used to the value in this variable. Now that we know how to change the theme, it is just a question of when to do it. Since we are looking to change it based on the day of the week, we are going to take advantage of a feature of PHP's date() function which returns the day of the week as a number between zero and six.

// Get the current day of the week in numerical form.
$day = date("w");

We now map the $day variable to the $themes array which also has elements from 0 to 6 associated with seven enabled themes and, as a result, we obtain the equivalent theme for that day of the week. Finally, assigning our result to the $custom_theme variable overrides the default theme with the theme for the current day of the week.

There's more...

The PHP code used in this recipe can be easily modified to display a random theme on every page load.

Displaying a random theme

Instead of displaying a preset theme for each day of the week, integrating the following snippet into the mysite_init() function will display a random theme on every page load:

// Override current theme randomly.
$custom_theme = $themes[array_rand($themes)];

Creating a fresh look using the color module

The color module allows the administrator to easily change the color scheme of themes that support it. This facilitates a fresh look for the site without having to create a new theme or sub-theme. Drupal's default theme, Garland, supports the color module and, in this recipe, we will be covering the steps required to change its color scheme to something unique.

Getting ready

Ensure that the color module is enabled in admin/build/modules (Home | Administer | Build | Modules). Since we are going to change the color scheme of the Garland theme, ensure that it is set as the current theme.

How to do it...

Colorizing the Garland theme can be accomplished by following these steps:

  1. Navigate to admin/build/themes (Home | Administer | Build | Themes).
  2. Look for the Garland theme and click on the configure link next to it.
  3. Look for the section titled Color scheme.
  4. In this section, the Color set drop-down lists available presets. Choosing any of the presets will change the color scheme of the preview section further below.

  5. Once satisfied, click on the Save configuration button at the bottom of the page to save our changes.

How it works...

The color module works by generating stylesheets using the new color scheme which effectively replace the existing stylesheet during runtime. The generated CSS file is stored in the site's files directory in a folder named color. In addition to the stylesheets, the color module, when configured correctly as with the Garland theme, can also blend the theme's image assets to suit the new color scheme.

The color module creates a new stylesheet which is a customized copy of the theme's original CSS file. Since it is a copy, fixes and updates to the original file are not automatically propagated to it. Therefore, whenever changes are made to the original file, It is recommended that the stylesheet be regenerated by simply saving the customized color settings once again.

There's more...

We are not restricted to the inbuilt presets provided by the color module and can also create our own.

Custom presets

If the provided presets are unsatisfactory, clicking on the textfields below the drop-down will allow further customization. Once a textfield has focus, the color wheel on the right can also be clicked and used to select different palettes at will. These new settings are saved as the Custom preset as demonstrated in the following screenshot:


In this article we took a look at recipes dealing with adding and optimizing CSS files.

Further resources on this subject:

You've been reading an excerpt of:

Drupal 6 Theming Cookbook

Explore Title