demosthenes.info

Independent notes on CSS, SVG, animation and front-end design.

Articles / Article

Auto-generated CSS3 Prefixes With PHP

A simple way of generating vendor prefixes for stylesheets.

Each browser supports CSS proposals with CSS3 vendor-specific prefixes until the property is approved and finalized by the W3C. Sometimes browsers have different ways of writing values (as Firefox and Safari do with gradients), but for most proposals, the order and units used for CSS3 properties are the same: the only thing that changes is the vendor prefix. That means a lot of repetition in writing code. The following declaration is typical:

  1. div#box { -moz-border-radius: 5px; -o-border-radius: 5px;
  2. -ms-border-radius: 5px; border-radius: 5px; }

More code means more opportunities for mistakes, and produces stylesheets that are difficult to maintain. Rather than typing the vendor-specific prefix and values over and over again, we can use PHP to generate some it for us.

That means doing something that appears counter-intuitive at first: rather than linking our pages to a CSS file, we link to a PHP file instead:

  1. <link rel=”stylesheet” type=”text/css” href=”styles.php” />

One of the neat PHP functions that we’ve looked at in the past is header(). Previously, we used it to redirect a link; now, we are going to use it to fool the browser into believing that styles.php is actually a CSS file. As the very first line in styles.php, write:

  1. <?php header(‘Content-type: text/css’); ?>

That’s it. The browser will now take any CSS we provide, including any CSS that is generated by PHP, as if it was a real stylesheet. (It’s important to note that we can do all the scripting we like on this page, but the final output that the browser sees must be CSS… ideally, valid CSS.)

Using PHP to repeatedly produce CSS3 means we should write our code as a function. The function will need to know two things: the base property name (for example, border-radius) and the value associated with it (“5px”). So, joining our code at the top of the page, we write:

  1. <?php header(‘Content-type: text/css’);
  2. function css3_write ($property, $value) {
  3. } ?>

Within the curly braces, we want to produce the appropriate CSS declaration for all the browsers, prefixed with the correct vendor. The final base property will be at the end, as a fallback position. We’ll build up the declaration as the value of a $css3 variable, using a series of concatenations. We’ll also utlise the \n “new line” escape character to make the CSS the function creates more readable.

  1. <?php header(‘Content-type: text/css’);
  2. function css3_write ($property, $value) {
  3. $css3 = "-webkit-".$property.": ".$value.";\n"
  4. ." -moz-".$property.": ".$value.";\n"
  5. ." -o-".$property.": ".$value.";\n"
  6. ." -ms-".$property.": ".$value.";\n"
  7. ." ".$property.": ".$value.";\n";
  8. echo $css3;
  9. } ?>

To produce our CSS3, we just call the function with the appropriate CSS3 property and value at any point inside a CSS declaration:

  1. div#box { border: 1px solid black; background: #fff;
  2. <?php css3_write(“border-radius”, “5px”); ?> width: 50%;
  3. <?php css3_write(“box-shadow”, “5px 5px 2px rgba(0, 0, 0, 0.5)”); ?> }

Which will produce the following CSS:

  1. div#box { border: 1px solid black; background: #fff;
  2. -webkit-border-radius: 5px;
  3. -moz-border-radius: 5px;
  4. -o-border-radius: 5px;
  5. -ms-border-radius: 5px;
  6. border-radius: 5px; width: 50%;
  7. -webkit-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
  8. -moz-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
  9. -o-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
  10. -ms-box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5);
  11. box-shadow: 5px 5px 2px rgba(0, 0, 0, 0.5); }

A few points of note:

  • The CSS code produced is somewhat redundant, in that we are outputting CSS3 vendor prefixes for every possible browser every time. A more elegant solution (with a slightly higher hit in server-side processing) would be to detect the kind of browser requesting the stylesheet and produce only the CSS3 appropriate to that client.

  • Generating CSS on-demand in this way means that the stylesheet will never be cached by the browser (PHP files cannot be cached client-side, for obvious reasons). This will increase download times slightly. Alternatively, you could use the same script to simply output CSS, view it in your own browser, and copy and paste the produced code into a standard styles.css file, uploading that to your server and linking to it as normal from your pages. In that sense, the styles.php file would become the production template that you would use to generate a static CSS file for your site.

  • An alternative approach would be to use a CSS framework, which would produce much the same effect.