Dynamic cascading style sheets
internal or external?
Georges Trottier
August 9th 2010
updated October 16th 2014
Pick a color theme
blue   red   teal   brown   black

This article presents an easy way of using dynamic cascading style sheets that are linked to Web pages rather that used in-line. Session variables are used to inform the dynamic cascading style sheet of the color themes that are selected by the site administrator. Four color themes with three color shades are used on this Web site.

Update: The user interface of this site has been modified since this page was published so that the set of buttons allowing the user to switch theme no longer exists on the pages of this web site. I have added a set of buttons to implement this functionality (on this page only). I also made some editorial changes. More on this subject at A PHP way to simulate CSS Variables

A style is simply a rule describing how to format a particular portion of a web page. A style sheet is a set of such styles. They allow the HTML author to separate presentation from content in HTML documents. They are an amazing tool which has transformed Web Design as an industry and the Web as an effective communications medium. However, CSS has some flaws, the most frustrating of which is that . The corrective to this situation is: use dynamic cascading style sheets using PHP.

Cascading Style Sheets

Cascading Style Sheets (CSS) is a style sheet language used to describe the presentation semantics (the look and formatting) of a document written in a markup language [Wikipedia]. It is the result of past efforts by the Internet community to separate design from content. They come in three flavors: internal, external, and inline.

Internal CSS are inserted in the <head> section of the HTML page as in this exemple.

<style type="text/css">    
p {color: white; }  
body {background-color: black; }  
</style>  

However, when using CSS it is preferable to keep the CSS separate from the HTML. Placing CSS in a separate file allows the web designer to completely differentiate between content (HTML) and design (CSS). External CSS is a file that contains only CSS code and is saved with a ".css" file extension. This CSS file is then referenced in the HTML using the <link> instead of <style> tag.

<head>
  <link rel="stylesheet" type="text/css"  href="mystyle.css" />
</head> 

However, it is possible to place CSS right in the thick of the HTML code, and this method of CSS usage is referred to as inline CSS. It looks like this:

<p style="color:sienna;margin-left:20px">This is a paragraph.</p>

A lot of people think that PHP can only be used to deliver dynamic HTML pages. This is by no means the whole story! Did you know, for example, that with PHP you can deliver dynamic pseudo-CSS files? PHP is a free server-side scripting language which can be embedded in HTML code and cannot be disabled by the user. It provides various means of generating and enabling dynamic cascading style sheets.

The question that I raise here is: is it better to use internal or external dynamic cascading style sheets to enable dynamic-CSS?

Internal dynamic CSS

The display of my Web site is almost totally under the control of a dynamic CSS file which can display four different color themes (blue, brown, red and teal) with three shades of the selected color. Years ago, I used four cascading style sheets that I had to update and keep synchronized. The task was tedious, time consuming and prone to errors. As a result, about two years ago, I started using dynamic cascading style sheets without knowing it. I developed a CSS file with embedded PHP code and called it "gtrolayout.php". It displayed the pages in four color themes and the PHP code code enabling these color themes were embedded in the various styles of the CSS file.

Now I use only one pseudo-CSS file that I have called gtrolayout.php. The following snippet shows part of this file with the embedded PHP code:

#banner {
	color: <?php echo $Colors[2] ?>;
	text-align: center;
	width: 60%;
	margin: 0 auto;
	height: 200px;
	background-color:<?php echo $Colors[0] ?>;
	border: double 15px;
	border-radius: 50%;
	line-height: 50px;
}

My approach was been quite simple: in my site's PHP "page generator" program, I used the following code:

// Uses only one stylesheet for all themes
  if ($Theme == 'teal')
    $Colors< = array('#006633', '#66cc99', '#99ffcc');
  if ($Theme == 'blue')
    $Colors = array('#0000ff','#6666ff', '#ccccff');
  if ($Theme == 'brown')
    $Colors = array('#663300', '#cc9966', '#ffcc99');
  if ($Theme == 'red')
    $Colors = array('#FF0000', '#ff6666', '#ffcccc');
print '<STYLE TYPE="text/css">';
include_once $myIncPath . "gtrolayout.php";
print '</STYLE>';

Since the variable $Theme had been initialized to its default value (black) earlier in the code, the inclusion of the gtroloyout.php file produces an internal cascading style sheet that is embedded in the <head> portion of the page and the embedded PHP code is parsed and the values of $Colors[i] set to the proper values (without using another mean of passing the value). It displays the pages according to the selected color theme instantly. It works very well and allows a lot of flexibility.

External dynamic CSS

While the preceeding method works very well and is quasi immediate when the theme or the font size is modified interactively, I wondered if it would be possible to use a dynamic cascading style sheet containing PHP code externally (linked to the page rather than included). In fact, there is no problem if all the PHP variables of the file are initialized. If the external CSS file contains uninitialized variables which are set by the main program, the problem of passing the value of one or several variables to an external dynamic cascading style sheet is a very serious one.

Among the several methods that were investigated, I have examined two quite extensively. Here they are.

Storing the parameters in a session variable

A normal HTML website will not pass data from one page to another. In other words, all information is forgotten when a new page is loaded: in other words, HTML is stateless. A PHP session solves this problem by allowing you to store user information in an associative array on the server for later use but this session information is temporary and is usually deleted very quickly after the user has left the website that uses sessions.

Sessions work by creating a unique identification (UID) number for each visitor and storing variables based on this ID. This helps to prevent two users' data from getting confused with one another when visiting the same webpage.

In the code shown above, a theme (blue, brown, teal or red) has already been selected: it is the value of the $Theme variable. The sequence of if statements determines the array of colors associated with the selected theme and these values are saved in the session array variable. The dynamic cascading style sheet "gtrolayout.php" is then linked with the page as follows.

print '<link rel="stylesheet" href="' . $myWwwIncPath . 'gtrolayout.php" type="text/css">';

with gtrolayout.php evaluationg the session variables as follows:

if (isset($_SESSION['theme']))
  $Theme = $_SESSION['theme'];
else
  $Theme = 'teal';
if (isset($_SESSION['size']))
  $Font_Size = $_SESSION['size'];
else
  $Font_Size = 12;

The problem is that in all the tests that I have performed, the default values (black) was always returned meaning that $_SESSION[] was never set. I conclude that, if the values of the session variables are transmitted from page to page, they are not transmitted to the linked CSS file. Failure!

Using the values stored in the accessibility cookies

Suddenly, I had an idea. When any of the accessibility features is modified, the code creates a cookie with the value of the accessibility feature. Then, why not use these cookies to initialize the PHP variables in the pseudo-CSS file? gtrolayout.php is a pseudo-CSS file with embedded PHP code that looks like this:

<?php
header("Content-type: text/css; charset: UTF-8"); 
if (isset($_COOKIE['theme']))    // is cookie('theme') there?
	$Theme = $_COOKIE["theme"];      // set the theme
else $Theme = 'black';             // set to default theme
if ($Theme == 'teal')
  $Colors = array('#006633', '#66cc99', '#99ffcc')
if ($Theme == 'blue')
  $Colors = array('#0000ff', '#6666ff', '#ccccff');
if ($Theme == 'brown')
  $Colors = array('#663300', '#cc9966', '#ffcc99');
if ($Theme == 'red')
  $Colors = array('#FF0000', '#ff6666', '#ffcccc');
?>

...

#container{
  width: 90%;
  margin: 10 auto;
  text-align: left;
  border: 5px solid<?php< echo  $Colors[0] ?>;
    -moz-border-radius: 15px;
border-radius: 15px; overflow: hidden; background: url(../include/images/back.jpg); } ...

When the file is linked, the file is parsed by PHP and the values stored in the cookies are transmitted to the $Theme and $Font_Size local variable, the $Colors array variable become effective and the page is displayed correctly. On any modification performed by the user, the change in the display is almost immediate. For the first visit of a user, the CSS file is initialized with default values. It works!

The order of processing style sheets and cookies

Having perused a certain number of references, I think that I understand how cookies are dealt with on page refresh. Skipping details, when a client requests a page from a server, if there is a cookie associated with that page, the cookie is sent to the server.

Then, the HTML document gets downloaded and the parsing of the HTML document starts. As the cookie has been delivered to the server in the HTTP request, it is available for any $_COOKIE[] call.

When the HTML parsing reaches <style>...</style>, the pseudo-CSS file which starts with the $_COOKIE[] call is interpreted by PHP on the server, thus evaluating the cookie, before being downloaded to the browser in a separate thread (unaware of the main parsing thread) with the correct value of the color theme.

updated by the author on October 23rd 2014.

Implementation

Now that I have discussed the principles, let's see how the accessibility features are implemented.

Implementation of the change of themes

On the right side of this page, there is a demo selector that you can use to change the color themes. These squares are declared as links as follows

<a href= "<?php $FileName ?>?theme=blue"><img src="../include/images/color-blue.gif" alt="blue" /></a>
<a href= "<?php $FileName ?>?theme=brown"><img src="../include/images/brown.gif" alt="brown" /></a>
<a href= "<?php $FileName ?>?theme=red"><img src="../include/images/color_red.gif" alt="brown" /></a>
<a href= "<?php $FileName ?>?theme=teal"><img src="../include/images/color-teal.gif" alt="teal" /></a></td>

Selecting one of these links will load a new page to the browser with the same header followed by the value of the theme, say, www.gtro.com/web/dyncss_e.php?theme=teal. As the pseudo-CSS file cound not detect the change of theme and display it, I had to use a cookie for that purpose

The way cookies are implemented in the code

Cookies are small, often encrypted text files, located in browser directories. They are used by web developers to help users navigate their websites efficiently and perform certain functions. With cookies, the website sends information to the browser which then creates a cookie. Every time the user goes back to the same website, the browser retrieves and sends this file to the website's server [All about cookies].

In order to implement cookies, there is a need that each .php file associated with each page be declared as follows:

<?php ob_start(); ?>
<!DOCTYPE HTML>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Title</title>
<?php
	# Defines the root and paths to utility directories
	$RootDir = $_SERVER['DOCUMENT_ROOT']; 	// root of the site
	$myIncPath = $RootDir . '/include/';	// "include" folder
	# Define the page's specific parameters
  ...
	# Generation of the page
	include $myIncPath . "top.inc.php";		// generates the header and the templates
 include $myIncPath . "bottom.inc.php";  // generates the bottom of the page
?>

The <?php ob_start(); ?> statement is what is important here. Actually, ob_start() tells PHP to start output buffering, meaning that anything you output after ob_start() wont be sent to the browser until the end of the page or ob_end_flush() are reached. So that means that once you use ob_start() and echo something out, you can still set cookies without any errors.

The logic of the code is simple. If the page is sent to the browser as www.gtro.com/web/dyncss_e.php?theme=teal, it sets the theme to "teal" and create a cookie for that theme. If the page is sent to the browser as www.gtro.com/web/dyncss_e.php, it uses either the cookie['theme'] if it exists or the default theme ("black"). It is only after the cookies have been set that ob_end_flush() is called setting the output buffering off and sending the information to the browser.

Note that in the code above, setting the theme to "teal" will set the PHP variable $theme = "teal" so that the CSS file gtrolayout.php will react to it and display the "teal" color theme. The same is true for the font-size.

Conclusion

I have consulted several references as shown in the list that follows. The external pseudo-CSS file contained uninitialized variables which needed to be set by the main program: a very serious problem that I have solved using the values kept in a cookie located in the user's browser cache. Given that this cookie would not have been set, the code uses default values for the color theme ("black").

 

References

The following references were used while writing this article. Indebtedness is hereby acknowledged.

  1. "Des feuilles de style CSS dynamiques avec PHP"
  2. "Dynamic CSS with PHP"
  3. "Build Your Site With Dynamic CSS"
  4. Well House Consultant's "Using PHP to make dynamic style sheets"
  5. "Variables in your CSS via PHP" -
  6. Killersite.com "Dynamic CSS using PHP" - The following question is raised:"I need to pass it a VARIABLE...."
  7. Digital Web Magazine's "Generating dynamic CSS with PHP" - Answers the question in part...
  8. David Wassh Blog "CSS Variables using PHP" - CSS is an amazing formatting tool but it has one glaring omission: variables. In his My CSS Wishlist, he proposed a PHP-like syntax for CSS variables. Using PHP, he made the idea of easy, dynamic CSS a reality.
  9. BarelyFitz Design "CSS colors: take control with PHP" -
  10. Alex Jones "Dynamic CSS A.K.A. CSS Variables" -

    Warning!
    This code was developed for the pleasure of it. Anyone who decides to use it does so at its own risk and agrees not to hold the author responsible for its failure.


    Questions or comments?
    E-Mail
    Last modified: October 25th 2014 17:19:53. []