Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Web Design & Development > Usability

Web Design Reference Guide

Hosted by

Adding Functionality: Scripted CSS

Last updated Oct 17, 2003.

CSS was originally designed as a styling language, with an emphasis on keeping the syntax simple and as non-programmatic as possible.

Doing it this way encouraged adoption by designers who didn't get programming, while limiting those of us who want to take it further. Luckily, we can mix and match server-side scripting with CSS for powerful results.

While this article will use PHP for the examples, I'll try and explain the basic concepts in a general enough fashion that you can adapt the principles for ASP, Cold Fusion, or any other server-side language.

Templating

The most useful starting point for combining server-side code with CSS lies in templating. By now it's common practice for many developers to include common HTML fragments within multiple pages, decreasing overall maintenance. PHP uses the include statement to accomplish this. For example, a file called header.php might then include the basic markup that makes up the page header:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title><?php echo $pageTitle?></title>
<link rel="stylesheet" type="text/css" href="style.css" />

</head>
<body>

And within any other given page on the site, you'd expect to see the following PHP, which includes this markup from header.php and establishes any expected variables (as in the $pageTitle highlighted variable in the previous example):

<?php
      $pageTitle = "Demo";
      include("header.php");
?>

The HTML title element would get the specified text ("Demo" in this case) and the browser's title bar would be filled appropriately.

Body Classes

Perhaps you're in the practice of applying an id or a class to your body element. With scripted include files as in the above example, you could either set a single class or two that wouldn't change across all pages on your site, or you could include another variable in your individual pages that would establish unique body classes on a per-page or per-section basis. To achieve the latter, you'd change the final line within the previous header.php example from this:

<body>

To this:

<body class="<?php echo $bodyClasses?>">

And then you would ensure that within each individual page, you have an identically named variable setting either one or multiple body classes:

<?php
      $pageClasses = "sectionHomePage archives";
      $pageTitle = "Demo";
      include("header.php");
?>

In your style sheet, you now have the ability to style each individual page based on its body class. (A few of the more useful benefits are outlined in a WaSP interview [production note: link "WaSP interview" to this URL: http://www.webstandards.org/learn/articles/rcarver//#q7 ]) from 2004.)

Selective CSS Imports

Let's say you want to go further than simple body classes. If you've read part one of this series [production note: link "part one" to this URL: http://www.informit.com/guides/content.asp?g=webdesign&seqNum=236 ], you'll know that I advocate splitting up a site's CSS file into multiple, section-specific files. Again, the solution lies in custom per-page variables.

A basic way to accomplish this is a simple adaptation of the page class method above. Somewhere in header.php within the <head> and </head> tags, you will need a call to an external CSS file. We'd better wrap this one in an if statement to make sure that a URL exists though, as it's possible that some (or indeed, many) pages on the site won't need a custom external CSS file and it wouldn't make sense to include the markup:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title><?php echo $pageTitle?></title>
<link rel="stylesheet" type="text/css" href="style.css" />

<?php
      if ($customCSS) {
echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $customCSS . "\" />\n";
      }
?>
</head>

<body>

And again, to make use of this function we simply assign the URL of the external CSS file to the $customCSS variable:

<?php
      $customCSS = "/css/section-home-page.css";
      $pageClasses = "sectionHomePage archives";
      $pageTitle = "Demo";
      include("header.php");
?>

The method I prefer to work with takes into account the possibility of there being multiple external CSS files that could be called in from any page. Planning for the future never hurts, especially if you're working with a site that will grow over time.

Instead of simply including a link to one external file, we need a simple bit of code that will a) check for the existence of an array of URLs, and b) if it exists, loop through each value and include it as an external file. This way we don't include any extra markup in the page if the array hasn't been specified in the page, and we can then theoretically include as many links to external CSS files as we want.

The example code to do this in header.php looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

<head>
<title><?php echo $pageTitle?></title>
<link rel="stylesheet" type="text/css" href="style.css" />

<?php
      if ($customCSS) {
            $counted = count($customCSS);
            for ($i = 0; $i < $counted; $i++) {
                  echo " <link rel=\"stylesheet\" type=\"text/css\" href=\"" . $customCSS[$i] . "\" media=\"screen, projection\" />\n";
            }
      }
?>

</head>
<body>

And then within each page, we simply assign various URLs to the array as needed (or not at all, if not needed):

<?php
      $customCSS[0] = "/css/section-home-page.css";
      $customCSS[1] = "/css/archives.css";
      $customCSS[2] = "/css/classic.css";
      $pageClasses = "sectionHomePage archives";
      $pageTitle = "Demo";
      include("header.php");
?>

Dynamic CSS

Another direction we can explore is directly mixing server-side code in with our CSS. There are two important things we need to know, however. First, a web server will likely not run code within a file with an extension of .css by default; we need to either manually configure it (or trick it). Second, and more importantly – unlike a static CSS file, a dynamically processed file is expected to change often. If we don't watch it, a user's browser might not cache the file. That would be disastrous, as part of the reason for using CSS in the first place is the fact that external files cache so well.

The first has an easy fix. Instead of naming your CSS file whatever.css, simply name it whatever.php (or the extension of your scripting language of choice) and reference as you normally would within an HTML file, like so:

<link rel="stylesheet" type="text/css" href="whatever.php" />

There are further methods involving an .htaccess file that will allow you to make use of the .css file extension, but those require in-depth explanation that would go beyond the scope of this article; if you're interested, a quick Google search for "dynamic css htaccess" should provide all the explanation you'll need.

The caching issue requires a few lines of PHP within the file itself:

header("content-type:text/css");
header("Expires: " . gmdate("D, d M Y H:i:s", (time()+86400)) . " GMT");

The first line above ensures that the server sets the correct content type for the document, and serves it as it would serve any other CSS file. The second line sets the expiry date a day in the future (86,400 seconds = 24 hours * 60 minutes * 60 seconds), which ensures that the resulting CSS file will cache in a user's browser as long as they're visiting the site that day. And you may even wish to increase that time frame, if you expect multiple repeat visits from the same user.

Once you've ensured your PHP-enhanced CSS file caches properly, what can you do with it? Anything you can normally do with PHP.

For example, consider how nice it might be to be able to define a particular hex color value as a constant, and re-use that throughout the rest of the file. With a scripted CSS file, you can:

<?php
header("content-type:text/css");
header("Expires: " . gmdate("D, d M Y H:i:s", (time()+86400)) . " GMT");

      $magenta = "#c613d9";
?>

body {
      background: <?php echo $magenta;?>;
}
#header {
      background: <?php echo $magenta;?>;
}

And that's just the tip of the iceberg. If you're interested in pursuing the idea further, it's worth looking at some of the existing CSS + PHP articles and libraries already out there. Shaun Inman's CSS-SSC is a great start.