The Definitive Guide to Drupal 7

Adding, Removing, and Replacing CSS Files

There are three ways to manipulate CSS files within Drupal themes. This section will explain what the implementation options are, the reasons for each method, and when it’s advantageous to use certain methods over others.

Quick and Dirty Stylesheets via .info Files

Adding stylesheets via your theme’s .info file is the easiest way to add a CSS file to your theme; see Listing 16–37 and Listing 16–38. However, there are a few drawbacks to doing this in certain situations.

  1. Any stylesheet you define in the .info file will load on every page.
  2. You don’t have the full use of the features available in drupal_add_css(). For example, you can’t add conditional stylesheets for Internet Explorer or change the weight of a module’s CSS file in your .info file.
Listing 16–37. .info syntax for adding stylesheets
  1. stylesheets[CSS media type][] = path/to/file.css
Listing 16–38. Typical .info stylesheet definition example
  1. stylesheets[all][] = css/layout.css
  2. stylesheets[all][] = css/style.css
  3. stylesheets[print][] = css/print.css

Conditionally Loading Stylesheets with drupal_add_css()

drupal_add_css() is the main function used by modules and themes to add CSS files via PHP code. Some themes use it in their template.php file, typically within preprocess functions. One of the advantages of using drupal_add_css() in the theme layer as opposed to defining CSS files in a .info file is that files can be conditionally loaded based on certain criteria or context. For example, you may want to create a special CSS file that only loads on your site’s home page. In your theme’s template.php, you could do this within template_preprocess_html(), as shown in Listing 16–39.

Listing 16–39. Adding a stylesheet that loads only on the home page
  1. <?php
  2. function mytheme_preprocess_html(&$variables) {
  3. // Add a stylesheet that prints only on the homepage.
  4. if ($variables['is_front']) {
  5. drupal_add_css(path_to_theme() . '/css/homepage.css', array('weight' => CSS_THEME));
  6. }
  7. }

There are many different options for adding CSS to your pages in Drupal using drupal_add_css(), some of which include:

  • Specifying the type as “inline” to print a block of CSS code within <head>, as opposed to adding a CSS file.
  • Specifying the “group” of a file to determine where the file should appear using constants such as CSS_SYSTEM (top), CSS_DEFAULT (middle), and CSS_THEME (bottom).
  • Specifying the “weight” of a file to control the order in which it loads within its group.
  • Adding conditional stylesheets to serve different files to different browsers.
  • Adding externally hosted CSS files.
  • Forcing a CSS file to be excluded from the aggregation and compression process.

Adding Conditional Stylesheets for Internet Explorer

According to Wikipedia at the time of this writing, about 43 percent of users are visiting web pages using Internet Explorer. This statistic varies from source to source, but for many of you, supporting older versions of Internet Explorer is a fact of life. Using conditional stylesheets is considered a best practice when the need arises to write CSS that targets Internet Explorer.

One of the great new features in Drupal 7 is that conditional stylesheets can be added using drupal_add_css(). In fact, all three of Drupal’s core themes do this in template_preprocess_html(). The reason this is done in template.php is that .info files only have very basic support for drupal_add_css(). Listing 16–40 and Listing 16–41 demonstrate how this works using code from the Seven theme as an example.

Listing 16–40. Excerpt from the Seven theme, using drupal_add_css() to add conditional stylesheets for IE in template_preprocess_html()
  1. <?php
  2. function seven_preprocess_html(&$variables) {
  3. // Add conditional CSS for IE8 and below.
  4. drupal_add_css(path_to_theme() . '/ie.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 8', '!IE' => FALSE), 'preprocess' => FALSE));
  5. // Add conditional CSS for IE6.
  6. drupal_add_css(path_to_theme() . '/ie6.css', array('group' => CSS_THEME, 'browsers' => array('IE' => 'lt IE 7', '!IE' => FALSE), 'preprocess' => FALSE));
  7. }
Listing 16–41. The source code that results from adding IE conditional stylesheets with drupal_add_css()
  1. <!--[if lte IE 8]>
  2. <link type="text/css" rel="stylesheet" href="http://drupal-7/themes/seven/ie.css?l40z2j" media="all" />
  3. <![endif]-->
  4. <!--[if lt IE 7]>
  5. <link type="text/css" rel="stylesheet" href="http://drupal-7/themes/seven/ie6.css?l40z2j" media="all" />
  6. <![endif]-->

The code in Listing 16–40 and Listing 16–41 gives you two conditional stylesheets that will load for Internet Explorer only. The first stylesheet will load for Internet Explorer 8 and under, and the second stylesheet will load for versions of Internet Explorer prior to IE7.

Completely Control Stylesheets Using hook_css_alter()

Drupal core and modules add CSS files individually via the drupal_add_css() function. During template_process_html()</a>, a variable called <code lang="php">$styles is created; it contains the fully formatted HTML output for all the stylesheets that are specified for each page. This variable is eventually printed inside the <head> tags in the html.tpl.php template file, as shown in Listing 16–42.

Listing 16–42. $styles variable is created in template_process_html() for use in html.tpl.php
  1. <?php
  2. /**
  3.  * Implements template_process_html().
  4.  */
  5. function template_process_html(&$variables) {
  6. ...
  7. $variables['styles'] = drupal_get_css();
  8. ...
  9. }

During the call to drupal_get_css(), Drupal gathers up all the CSS files previously added, and then provides an opportunity for any modules or themes to make changes by calling drupal_alter('css', $css). At this time, Drupal looks for functions in modules and themes that fit the naming pattern hook_css_alter(), where the word “hook” in the function name is replaced by the module or theme name implementing it. This function allows for the most granular control over all aspects of your CSS files.

An example of why a module might want to implement hook_css_alter() can be found in the Locale module. The Locale module checks to see if the language direction is right-to-left, and if so, finds the related RTL versions of the CSS files and adds them to the page.

In themes, the main reasons to implement hook_css_alter() is to remove or override CSS files provided by modules. An example of this can be found at the bottom of Seven theme’s template.php file (see Listing 16–43). Seven chooses to override the stylesheet vertical-tabs.css file provided by core with its own version.

Listing 16–43. The Seven theme’s hook_css_alter() implementation
  1. <?php
  2. /**
  3.  * Implements hook_css_alter().
  4.  */
  5. function seven_css_alter(&$css) {
  6. // Use Seven's vertical tabs style instead of the default one.
  7. if (isset($css['misc/vertical-tabs.css'])) {
  8. $css['misc/vertical-tabs.css']['data'] = drupal_get_path('theme', 'seven') . '/vertical- tabs.css';
  9. }
  10. // Use Seven's jQuery UI theme style instead of the default one.
  11. if (isset($css['misc/ui/jquery.ui.theme.css'])) {
  12. $css['misc/ui/jquery.ui.theme.css']['data'] = drupal_get_path('theme', 'seven') . '/jquery.ui.theme.css';
  13. }
  14. }

You are reading content from two chapters on Theme Development from The Definitive Guide to Drupal 7, written by Jacine Luisi and published by Apress on July 19, 2011. All rights reserved.