A Practical Example of Dynamic CSS

Continuing with the idea of dynamic CSS Stylesheets using PHP, I constructed a basic working example. See this page for details on how you might configure Apache to do this.

Once you have played with the settings, try viewing this page, which is not getting any information from this page (or the iframe) but only keeps the same style because it includes the same style sheet (and the stylesheet knows your settings from the Cookies in your browser!)

Addressing the Practical Problems of Dynamic CSS

Besides the obvious initial issue of getting Apache to pre-treat the CSS files with PHP, there were a number of other practical issues that needed to be solved. I began by creating a dynamic CSS Stylesheet, who’s settings were taken entirely from the COOKIES of the requesting computer:

dynamic.css
[ download ]

<?php header("Content-type: text/css"); ?>

body {

 background-color:<?php echo $_COOKIE['roger_davies_back_colour']; ?>;
 font-family:<?php echo $_COOKIE['roger_davies_font_face']; ?>; 

}

h1 {	font-size:<?php echo $_COOKIE['roger_davies_header_size'];  ?>;
	color:<?php echo $_COOKIE['roger_davies_text_colour'];?>;
}

p { <?php if (isset($_COOKIE['roger_davies_text_colour']))
		{ echo "color:".$_COOKIE['roger_davies_text_colour'];  }
?>;  }

a { <?php if (isset($_COOKIE['roger_davies_text_colour']))
		{ echo "color:".$_COOKIE['roger_davies_link_colour'];  }
?>;  }

Testing Cookies Are Set Before Testing Their Value

But we need to be careful to ensure that the cookies are set by the time the PHP processor gets to this section of code, otherwise our stylesheet will start to fill with : code like: “a { color:notice : undefined index }”. This makes it essential that we test the cookies at the start of our HTML document(s), and to set them to some initial value (if not already set) before the clients browser reaches the link to the stylesheet. Also, each time you query the COOKIE, you must test isset(…) first. I used PHP’s lazy evaluation using double ampersand : “if (expression 1 && expression 2) …” which will try to evaluate expression 1 first, then ONLY try to evaluate expression 2 if expression 1 is true. This way, provided we keep the Isset command as expression 1, we can be sure it will never test a cookie or value that isn’t set. In larger sites, the initial-value-setting (block before the opening <HTML> element) is probably best done with an include (I’ve coded it into the HTML file here to keep the example simple).

While working on this, I found it useful to look at the CSS sheet directly with my browser by entering the URL to ensure the dynamic CSS stylesheet was being built by the PHP correctly. Remember, you won’t see any error messages because they will be printed in the stylesheet, not the HTML document!

index.html
[ download ]

<?php

	if (isset($_GET['backgroundcolour'])) {	setcookie("roger_davies_back_colour", $_GET['backgroundcolour']); }
	if (isset($_GET['textcolor'])) {	setcookie("roger_davies_text_colour", $_GET['textcolor']); }
	if (isset($_GET['headersize'])) {	setcookie("roger_davies_header_size", $_GET['headersize']); }
	if (isset($_GET['linkcolour'])) {	setcookie("roger_davies_link_colour", $_GET['linkcolour']); }
	if (isset($_GET['fontface'])) {	setcookie("roger_davies_font_face", $_GET['fontface']); }

	if (!isset($_COOKIE['roger_davies_back_colour'])) { setcookie ("roger_davies_back_colour", "White"); }
	if (!isset($_COOKIE['roger_davies_text_colour'])) { setcookie ("roger_davies_text_colour", "black"); }
	if (!isset($_COOKIE['roger_davies_header_size'])) { setcookie ("roger_davies_header_size", "14px"); }
	if (!isset($_COOKIE['roger_davies_link_colour'])) { setcookie ("roger_davies_link_colour", "Blue"); }
	if (!isset($_COOKIE['roger_davies_font_face'])) { setcookie ("roger_davies_font_face", "Times New Roman"); }

?>
<html>
<head>
<title>PHP CSS Files - Dynamic CSS test using PHP in the CSS Stylesheet</title>
<meta name="description" content="php css files, php, css, dynamic css, php in css stylesheets" />
<meta name="keywords" content="PHP CSS Files - Dynamic CSS test using PHP in the CSS Stylesheet" />
<link href="dynamic.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form action="index.html" method="get">
<p style="color:black; background-color:white;"><strong>Select BACKGROUND Color:</strong><SELECT name="backgroundcolour">

      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "White")) { echo " SELECTED"; } ?>>White</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Black")) { echo " SELECTED"; } ?>>Black</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Purple")) { echo " SELECTED"; } ?>>Purple</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Red")) { echo " SELECTED"; } ?>>Red</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Blue")) { echo " SELECTED"; } ?>>Blue</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Green")) { echo " SELECTED"; } ?>>Green</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Cyan")) { echo " SELECTED"; } ?>>Cyan</OPTION>
      <OPTION<?php if (isset($_GET['backgroundcolour']) && !strcmp($_GET['backgroundcolour'], "Magenta")) { echo " SELECTED"; } ?>>Magenta</OPTION>
   </SELECT></p>
<p  style="color:black; background-color:white;"><strong>Select FOREGROUND Color:</strong><SELECT name="textcolor">
 <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "White")) { echo " SELECTED"; } ?>>White</OPTION>
      <OPTION<?php if ((isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Black")) || !isset($_GET['textcolor']) ) { echo " SELECTED"; } ?>>Black</OPTION>
      <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Purple")) { echo " SELECTED"; } ?>>Purple</OPTION>
      <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Red")) { echo " SELECTED"; } ?>>Red</OPTION>
      <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Blue")) { echo " SELECTED"; } ?>>Blue</OPTION>
      <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Green")) { echo " SELECTED"; } ?>>Green</OPTION>
      <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Cyan")) { echo " SELECTED"; } ?>>Cyan</OPTION>
      <OPTION<?php if (isset($_GET['textcolor']) && !strcmp($_GET['textcolor'], "Magenta")) { echo " SELECTED"; } ?>>Magenta</OPTION>
   <input type="hidden" name="posted" value"done"></p>
<p style="color:black; background-color:white;"><strong>Select HEADER Size:</strong><SELECT name="headersize">
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "6px")) { echo " SELECTED"; } ?>>6px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "10px")) { echo " SELECTED"; } ?>>10px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "12px")) { echo " SELECTED"; } ?>>12px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "14px")) { echo " SELECTED"; } ?>>14px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "16px")) { echo " SELECTED"; } ?>>16px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "18px")) { echo " SELECTED"; } ?>>18px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "22px")) { echo " SELECTED"; } ?>>22px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "24px")) { echo " SELECTED"; } ?>>24px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "28px")) { echo " SELECTED"; } ?>>28px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "36px")) { echo " SELECTED"; } ?>>36px</OPTION>
      <OPTION<?php if (isset ($_GET['headersize']) && !strcmp($_GET['headersize'], "48px")) { echo " SELECTED"; } ?>>48px</OPTION>
   <input type="hidden" name="posted" value"done"></p>

<p style="color:black; background-color:white;"><strong>Select Link Colour:</strong><SELECT name="linkcolour">
      <OPTION<?php if ((isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Blue")) | !isset($_GET['linkcolour'])) { echo " SELECTED"; } ?>>Blue</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Green")) { echo " SELECTED"; } ?>>Green</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Red")) { echo " SELECTED"; } ?>>Red</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Orange")) { echo " SELECTED"; } ?>>Orange</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Yellow")) { echo " SELECTED"; } ?>>Yellow</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Purple")) { echo " SELECTED"; } ?>>Purple</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Cyan")) { echo " SELECTED"; } ?>>Cyan</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Magenta")) { echo " SELECTED"; } ?>>Magenta</OPTION>
      <OPTION<?php if (isset ($_GET['linkcolour']) && !strcmp($_GET['linkcolour'], "Pink")) { echo " SELECTED"; } ?>>Pink</OPTION>
   <input type="hidden" name="posted" value"done"></p>
   <INPUT type="submit" value="Send"><INPUT type="reset">
<p style="color:black; background-color:white;"><strong>Select Font Style:</strong><SELECT name="fontface">
      <OPTION<?php if ((isset ($_GET['fontface']) && !strcmp($_GET['fontface'], "Arial, sans-serif")) | !isset($_GET['linkcolour'])) { echo " SELECTED"; } ?>>Arial, sans-serif</OPTION>
      <OPTION<?php if (isset ($_GET['fontface']) && !strcmp($_GET['fontface'], "Helvetica, sans-serif")) { echo " SELECTED"; } ?>>Helvetica, sans-serif</OPTION>
      <OPTION<?php if (isset ($_GET['fontface']) && !strcmp($_GET['fontface'], "Times New Roman, serif")) { echo " SELECTED"; } ?>>Times New Roman, serif</OPTION>
      <OPTION<?php if (isset ($_GET['fontface']) && !strcmp($_GET['fontface'], "Courier New, monospace")) { echo " SELECTED"; } ?>>Courier New, monospace</OPTION>
      <OPTION<?php if (isset ($_GET['fontface']) && !strcmp($_GET['fontface'], "Comic Sans, Comic Sans MS, cursive")) { echo " SELECTED"; } ?>>Comic Sans, Comic Sans MS, cursive</OPTION>
      <OPTION<?php if (isset ($_GET['fontface']) && !strcmp($_GET['fontface'], "Impact, fantasy")) { echo " SELECTED"; } ?>>Impact, fantasy</OPTION>
   <input type="hidden" name="posted" value"done"></p>
   <INPUT type="submit" value="Send"><INPUT type="reset">
</form>
<h1>Header</h1>
<p>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</p>
<a href="page.html">View a completely independent page</a> using this stylesheet you have edited</a>
</body>
</html

Imagining The Possibilities

This example is very basic – just allowing the user to twiddle colours and some styles of the elements, but imagine what is possible when this is scaled up to a full website! Not only could you allow each user to choose a skin they view your site in, but might also individually alter some of the styling themselves, which would be unique to just them! When I first began learning CSS, I found The CSS Zen Garden very useful to help me reach the realisation that the design and the style could be thought of as two completely separate entities. This method takes it a few steps further, that each person has their own stylesheet that is generated for them alone. I think there could be futher amazing applications for this, and I hope to at least give people something to think about.