I recently posted about creating some Baseline Grid CSS for my web typography. The first iteration was hand-coded for a specific font-size and line-height. A reader mentioned that there are CSS templating engines available called LESS and SASS respectively. They both allow you to treat CSS more like a real programming language, with constants and functions and other extensions to make it suck less. SASS works on the server-side, requiring Ruby. LESS, however, runs on the client-side, and is implemented as a Javascript library that executes at runtime. There are some nice features in both packages, but I didn’t really want to require yet another Javascript library in my code or install Ruby.
Why not use PHP?
The alternative, of course, is using PHP. Most PHP tutorials I saw on the subject required loading a templating engine like Smarty or littering your CSS with stupid-looking PHP “ tags. I hate the way that looks, and it makes for awkward typing.
So I tried something a lot simpler.
Getting rid of those ugly <? tags ?>
I used the new-ish PHP5 __halt_compiler()
command to make a single-file, self-contained templating system. The “constants” are defined above the template “engine”, which is basically 7 lines of PHP tucked between lines 14 and 23 (below). After the engine code is normal syntax CSS file, with the addition of the template constants.
Here’s an abbreviated exmample of my baseline.css.php
file; it’s included in HTML as a stylesheet with the normal <link rel='stylesheet'...
statement.
<?php // Basic Typographic Dimensions: $basefontSize = 12; $gridSize = 18; $substitutions = array( '@timestamp' => date('Y-m-d h:i:s'), '@basefont' => $basefontSize . 'px', '@grid' => $gridSize . 'px', '@basecolor' => '#444' ); /** DO REPLACEMENT ************************************/ $fp = fopen(__FILE__,'r'); fseek($fp,__COMPILER_HALT_OFFSET__); $output = stream_get_contents($fp); foreach ($substitutions as $key=>$value) $output = str_replace("[$key]",$value,$output); header("Content-type: text/css"); print $output; __halt_compiler(); /** BEGIN CSS ** GENERATED OUTPUT ** [@timestamp] **/ body { font-size: [@basefont]; line-spacing: [@grid]; color: [@basecolor]; }
In particular:
- On line 7, you define an array of the values you want to substitute. For example,
@basefont
is matched with a string containing the value of$basefontSize
and the letterspx
. On line 23 is the beginning of the actual CSS. Anywhere there is a
[@basefont]
(note the brackets), the value defined above will be substituted.
<
p>That’s it!
How It Works
Here’s what the code does:
- When the file is loaded by the browser, the PHP code opens ITSELF. The code uses the
fseek()
command to skip over the PHP to process the end of the file where my CSS code lives. - Everything after the
__halt_compiler()
command is read into the variable$output
. This should have normal CSS code in it. - It uses the
str_replace()
function to substitute the keys (e.g.@basefont
) in$substitutions
with the associated values (12px
, the result of the calculation). - Once all substitutions are done, the modified CSS is sent to the browser with the necessary
Content-Type: Text/css
HTTP header.
Since it’s PHP, you can write anything you want to pre-calculate anything you might need. With a little elbow grease, you could do more sophisticated parsing of the substitution keys, evaluate PHP code, or even call functions. All I really want for myself, though, is some simple arithmetic and maybe a few color definitions, so I think this is fine for now.
Drawbacks
It’s PHP, so that means if you make an error in the code, your CSS file will not load. And since the file is being fetched as a stylesheet file, you won’t see any errors unless you:
- Enable PHP Error Reporting, if it’s not already on.
- Go directly to the URL of the stylesheet in your browser so you can see the errors.
Or…
- Inspect the PHP Error Log on your web server. This is what I do, as I have a browser-accessible error log (here’s how I set it up on my Plesk-based CentOS server).
You might also forget to include all the @keys, or forget the [ ] around them. This is just an arbitrary convention I am using…you could use { } or whatever you like that is “search and replace”-friendly.
One last irritation is that since this is a PHP file, my code editor doesn’t syntax-highlight or auto-complete the CSS parts. I might convert this into a generalized loader that processes existing .css files to resolve that, but that sort of gets away from the one-file ideal. UPDATE: Besides, this is even simpler.
Check It Out
You can check out my working prototype and click on a few values to see how it recalculates. The templating should be fast enough to use for development, but for a production server you probably would want to copy the output into a static .css file. My code emits a timestamp to help keep things straight.
There are still errors in the baseline calculations due to loss of numerical precision, but the general idea seems to be working. Now I can quickly experiment with font and line height combinations to establish a particular typographic color and scale, with a pretty good starting point for the typography. If you’d like to play with the source code, you can download it here. Enjoy!
- Download ZIP archive of the baseline grid prototype, so you can see it working in a more complex example. Requires PHP5 on your webserver.
- Read about the Baseline Grid CSS stuff I’ve been experimenting with.
Other Solutions
Much thanks to the more clued-in developers for sending me these links. These are much more powerful processors, implemented in different ways toward the same goal of extending CSS with useful programmer features:
SASS or “Semantically Awesome Stylesheets” is a server-side CSS processor written in Ruby.
LESS.js is a “Dynamic Stylesheet Language” written in Javascript.
Joe Lencioni pointed me to the CSS Crush Preprocessor, which is a PHP implementation that looks tasty.
2 Comments
Thanks for this follow-up Dave. I like your simple PHP solution for basic variable handling.
I love the more efficient development with LESS/SASS – the advanced mixin and calculator features are incredibly powerful – but the requirement for Ruby or node.js for server-side processing rules them out for production use for any client using “bog standard” LAMP hosting.
Currently I’m using LESS with client-side processing for prototyping and development , then manually replacing with the processed CSS for the live site. My worry is at some point the manual step is going to be missed. There is a PHP processor for it, but it’s not fully compatible :(
CSS Crush looks a promising fully PHP solution which I hadn’t come across before. I’ll get my PHP expert Partner in Crime to have a look.
Instead of using
you can use heredoc. http://php.net/manual/en/language.types.string.php
Example: $color = “#900”; $margin = “10px”;
$str = <<<EOD
main_container{
} EOD;